http HEAD vs GET производительность

111

Я настраиваю веб-службу REST, которая просто должна ответить ДА или НЕТ как можно быстрее.

Создание службы HEAD кажется лучшим способом сделать это, но я хотел бы знать, действительно ли я выиграю некоторое время по сравнению с выполнением запроса GET.

Я полагаю, что поток тела не должен быть открыт / закрыт на моем сервере (около 1 миллисекунды?). Поскольку количество возвращаемых байтов очень мало, выиграю ли я какое-либо время при транспортировке в количестве IP-пакетов?

Заранее благодарим за ответ!

Редактировать:

Для дальнейшего объяснения контекста:

  • У меня есть набор служб REST, выполняющих некоторые процессы, если они находятся в активном состоянии.
  • У меня есть еще одна служба REST, показывающая состояние всех этих первых служб.

Поскольку эта последняя служба будет вызываться очень часто очень большим набором клиентов (один вызов ожидается каждые 5 мс), мне было интересно, может ли использование метода HEAD быть ценной оптимизацией? В теле ответа возвращается около 250 символов. Метод HEAD, по крайней мере, получил транспортировку этих 250 символов, но что это за влияние?

Я попытался измерить разницу между двумя методами (HEAD vs GET), выполнив в 1000 раз больше вызовов, но не увидел никакого выигрыша (<1 мс) ...

Астерий
источник
2
Это также зависит от подхода, который вы используете на стороне сервера. Обычно для обработки запроса GET или HEAD может потребоваться одно и то же время сервера, потому что серверу может потребоваться знать окончательное тело для вычисления Content-Lengthзначения заголовка, которое является важной информацией в ответе на запрос HEAD. Если не существует другого, более оптимизированного подхода на стороне сервера, единственное преимущество состоит в том, что полоса пропускания сохраняется, и клиенту не нужно анализировать тело ответа. Таким образом, в основном выгода от оптимизации зависит как от серверной, так и от клиентской реализации.
itsjavi

Ответы:

173

RESTful URI должен представлять «ресурс» на сервере. Ресурсы часто хранятся в виде записи в базе данных или файла в файловой системе. Если ресурс не велик или медленно извлекается на сервере, вы можете не увидеть ощутимого прироста при использовании HEADвместо GET. Может случиться так, что получение метаданных не быстрее, чем получение всего ресурса.

Вы можете реализовать оба варианта и протестировать их, чтобы увидеть, какой из них быстрее, но вместо микрооптимизации я бы сосредоточился на разработке идеального интерфейса REST. Чистый REST API обычно более ценен в долгосрочной перспективе, чем беспорядочный API, который может быть или не быть быстрее. Я не отговариваю от использования HEAD, просто предлагаю использовать его, только если это «правильный» дизайн.

Если информация, которая вам действительно нужна, представляет собой метаданные о ресурсе, которые могут быть красиво представлены в заголовках HTTP, или для проверки, существует ли ресурс или нет, HEADможет работать нормально.

Например, предположим, что вы хотите проверить, существует ли ресурс 123. А 200означает «да» и 404означает «нет»:

HEAD /resources/123 HTTP/1.1
[...]

HTTP/1.1 404 Not Found
[...]

Однако, если «да» или «нет», которые вы хотите получить от службы REST, является частью самого ресурса, а не метаданными, вы должны использовать GET.

Андре Д
источник
3
лучшие вещи всегда просты, как и этот ответ. Вуаля!
Afzal SH
Замечательный ответ! У меня вопрос: как насчет того, чтобы использовать его в качестве touchкоманды для обновления количества просмотров поста на сервере? Данные сообщения уже были получены с помощью обычного /postsвызова, поэтому я просто хочу обновить счетчик просмотров после того, как пользователь каким-либо образом взаимодействует с сообщением.
aalaap
1
@aalaap Если вы собираетесь обновить счетчик просмотров для HEADзапросов, вам следует сделать это и для GETзапросов. Решение использовать GETили HEADв конечном итоге остается за HTTP-клиентом. Ваш сервер должен вести себя одинаково для обоих типов запросов, за исключением того, что при ответе нет тела ответа HEAD. Что касается того, является ли это хорошим способом реализовать что-то вроде счетчика просмотров, я не уверен.
Andre D
-1 Любая информация, которую можно назвать, может быть ресурсом. Следовательно, Единый указатель ресурсов. Идея о том, что использование части протокола HTTP в том виде, в котором он был разработан, является «грязным» или «нечистым», является странной.
Fraser
1
@Siddhartha, это очень часто правда, но не всегда. Content-Lengthможет быть опущен при использовании Transfer-Encoding: chunked. Даже при Content-Lengthэтом возможно, что сервер может получить размер ресурса и другие метаданные, используемые в заголовках, без извлечения фактического ресурса. Возможно, эти метаданные даже кэшируются в памяти для очень быстрого доступа. Это все очень зависит от реализации.
Andre D
38

Я нашел этот ответ, когда искал тот же вопрос, который задал запрашивающий. Я также нашел это на http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html :

Метод HEAD идентичен GET, за исключением того, что сервер НЕ ДОЛЖЕН возвращать тело сообщения в ответе. Метаинформация, содержащаяся в заголовках HTTP в ответ на запрос HEAD, ДОЛЖНА быть идентична информации, отправленной в ответ на запрос GET. Этот метод можно использовать для получения метаинформации об объекте, подразумеваемом запросом, без передачи самого тела объекта. Этот метод часто используется для проверки гипертекстовых ссылок на достоверность, доступность и недавние изменения.

Мне кажется, что правильный ответ на вопрос запрашивающей стороны - это то, что это зависит от того, что представляет протокол REST. Например, в моем конкретном случае мой протокол REST используется для получения довольно больших (например, более 10 КБ) изображений. Если у меня есть большое количество таких ресурсов, которые проверяются на постоянной основе, и с учетом того, что я использую заголовки запросов, то, согласно рекомендациям w3.org, имеет смысл использовать запрос HEAD.

Чарльз Томас
источник
14

Я категорически против такого подхода.

Служба RESTful должна уважать семантику HTTP-глаголов. Глагол GET предназначен для извлечения содержимого ресурса, в то время как глагол HEAD не возвращает никакого содержимого и может использоваться, например, чтобы увидеть, изменился ли ресурс, узнать его размер или его тип, чтобы проверить, не изменился ли он. существует и так далее.

И помните: ранняя оптимизация - это корень всех зол.

Эрик Ситэр
источник
8

Ваша производительность вряд ли изменится при использовании запроса HEAD вместо запроса GET.

Кроме того, если вы хотите, чтобы он был REST-полным и вы хотите получать данные, вы должны использовать запрос GET вместо запроса HEAD.

болтовня
источник
8

GET - голова + тело, HEAD - только голова. Не должно быть вопросом мнения, какой из них быстрее. Я не понимаю приведенных выше ответов. Если вы ищете мета-информацию, то ищите HEAD, который предназначен для этой цели.

Виктор Жорас
источник
3

Я не понимаю вашего беспокойства о том, что «поток тела открыт / закрыт». Тело ответа будет в том же потоке, что и заголовки ответа http, и НЕ будет создавать второе соединение (которое, кстати, больше в диапазоне 3-6 мс).

Это похоже на очень преждевременную попытку оптимизации чего-то, что просто не будет иметь существенного или даже измеримого значения. Настоящая разница - это соответствие REST в целом, который рекомендует использовать GET для получения данных.

Мой ответ - НЕТ, используйте GET, если это имеет смысл, при использовании HEAD нет увеличения производительности.

Smassey
источник
Предположим, что содержимое составляет 100 МБ. Наверняка голова будет меньше содержимого по размеру. Теперь, когда мы запрашиваем этот ресурс методами GET или HEAD, по вашему мнению, нет разницы в производительности между ними ?!
Мохаммад Афраштех
3
ОП заявило 250 символов в теле ответа. Не 100 МБ. Это совсем другой вопрос.
smassey
1

Запросы HEAD аналогичны запросам GET , за исключением того, что тело ответа пусто. Этот тип запроса можно использовать, когда все, что вам нужно, это метаданные о файле, но не нужно транспортировать все данные файла.

Шадаб Али
источник
-1

Вы можете легко провести небольшой тест, чтобы самостоятельно измерить производительность. Я думаю, что разница в производительности будет незначительной, потому что, если вы возвращаете только «Y» или «N» в теле, это единственный дополнительный байт, добавленный к уже открытому потоку.

Я бы также пошел с GET, так как это более правильно. Вы не должны возвращать контент в заголовках HTTP, только метаданные.

AshleysBrain
источник
GET - это не только загадочный «один лишний байт». Просто все тело! В случае большого документа это может быть несколько мегабайт.
porfirion