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

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

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

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

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

Изменить:

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

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

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

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


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


Ответы (8)


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.

person Andre D    schedule 21.05.2013
comment
лучшие вещи всегда просты, как и этот ответ. Вуаля! - person Afzal S.H.; 08.12.2015
comment
Замечательный ответ! У меня вопрос: как насчет того, чтобы использовать его как команду touch для обновления количества просмотров публикации на сервере? Данные сообщения уже были получены с помощью обычного /posts вызова, поэтому я просто хочу обновить счетчик просмотров после того, как пользователь каким-либо образом взаимодействует с сообщением. - person aalaap; 04.09.2017
comment
@aalaap Если вы собираетесь обновить счетчик просмотров для HEAD запросов, вам следует сделать это и для GET запросов. Решение использовать GET или HEAD в конечном итоге остается за HTTP-клиентом. Ваш сервер должен вести себя одинаково для обоих типов запросов, за исключением того, что при ответе на HEAD нет тела ответа. Что касается того, является ли это хорошим способом реализовать что-то вроде счетчика просмотров, я не уверен. - person Andre D; 29.09.2017
comment
-1 Любая информация, которую можно назвать, может быть ресурсом. Следовательно, Единый указатель ресурсов. Идея о том, что использование части протокола HTTP в том виде, в котором он был разработан, является бессмысленным или нечистым, является странной. - person Fraser; 08.04.2018
comment
@Fraser Я не могу понять ваш комментарий, но вставка данных в заголовки HTTP только для того, чтобы их можно было получить с помощью запроса HEAD, не использует протокол, как задумано. - person Andre D; 04.07.2018
comment
@AndreD - возврат заголовков для ресурса через head не является беспорядочным, нечистым или забивающим данными - в вопросе OP они хотели знать об активном состоянии - так, например, - возвращение 404 для no / not found или 200 для да / found может быть вполне приемлемым, также использование 304 Not Modified вместе с заголовком запроса Etag может быть хорошим решением, позволяя клиенту просто проверять, изменилось ли активное состояние с момента последней проверки клиентом. Все это явно так, как разработан протокол HTTP. - person Fraser; 10.07.2018
comment
@Fraser Вы, кажется, неправильно поняли мой ответ. Использование 200/404 для «да / нет» было моим собственным предложением, которое я поддерживал как хорошее решение. Если вы хотите продолжить обсуждение, начните чат. - person Andre D; 10.07.2018
comment
@AndreD - Похоже, вы неправильно поняли мое возражение против этого. - person Fraser; 13.07.2018
comment
Unless the resource is large or is slow to retrieve at the server, you might not see a measurable gain by using HEAD instead of GET. У меня есть вопрос. Разве для HEAD вызова не нужно ли извлекать ресурс, большой ли он, чтобы вычислить Content-length? Значит, на стороне сервера и GET, и HEAD займут одно и то же время? Если серверу не удается вычислить длину контента без дорогостоящей выборки ресурсов ... - person Siddhartha; 24.05.2019
comment
@Siddhartha, это очень часто правда, но не всегда. Content-Length можно не указывать при использовании Transfer-Encoding: chunked. Даже с Content-Length возможно, что сервер сможет получить размер ресурса и другие метаданные, используемые в заголовках, без извлечения фактического ресурса. Возможно, эти метаданные даже кэшируются в памяти для очень быстрого доступа. Все это очень зависит от реализации. - person Andre D; 25.05.2019
comment
@AndreD Не мог бы попросить более подробного ответа, спасибо! - person Siddhartha; 25.05.2019
comment
прекрасный и простой ответ !! - person spandey; 19.06.2019

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

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

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

person Charles Thomas    schedule 03.09.2014

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

person Viktor Joras    schedule 26.05.2017

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

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

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

person Eric Citaire    schedule 22.05.2013

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

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

person jabbink    schedule 16.05.2013

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

person Shadab Ali    schedule 10.08.2019

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

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

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

person smassey    schedule 22.05.2013
comment
Предположим, что содержимое составляет 100 МБ. Наверняка голова будет меньше содержимого по размеру. Теперь, когда мы запрашиваем этот ресурс методами GET или HEAD, по вашему мнению, нет разницы в производительности между ними ?! - person Mohammad Afrashteh; 25.05.2018
comment
ОП заявило 250 символов в теле ответа. Не 100 МБ. Это совсем другой вопрос. - person smassey; 27.05.2018

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

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

person AshleysBrain    schedule 18.05.2013