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. Якщо є якийсь інший більш оптимізований підхід на стороні сервера, єдина перевага полягає в тому, що пропускна здатність зберігається і клієнту не потрібно аналізувати тіло відповідей. Таким чином, в основному досягнення оптимізації залежить як від серверної, так і від клієнтської реалізації.
ічанів

Відповіді:


173

RESTful URI повинен представляти "ресурс" на сервері. Ресурси часто зберігаються як запис у базі даних або файл у файловій системі. Якщо ресурс не є великим або на сервері його неможливо отримати, ви можете не побачити вимірюваного посилення, використовуючи HEADзамість GET. Можливо, завантаження метаданих не швидше, ніж отримання всього ресурсу.

Ви можете реалізувати обидва варіанти та порівняти їх, щоб побачити, що швидше, але замість мікрооптимізації я б зосередився на розробці ідеального інтерфейсу REST. Чистий API REST, як правило, більш цінний у довгостроковій перспективі, ніж API kludgey, який може бути, а може і не бути швидшим. Я не перешкоджаю використанню HEAD, просто пропоную використовувати його лише в тому випадку, якщо це "правильний" дизайн.

Якщо потрібна інформація насправді - це метадані про ресурс, який може бути добре представлений у заголовках HTTP або для перевірки того, чи існує ресурс чи ні, HEADможе працювати добре.

Наприклад, припустимо, ви хочете перевірити, чи існує ресурс 123. Засіб 200"так" і 404"ні":

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

HTTP/1.1 404 Not Found
[...]

Однак якщо потрібне "так" або "ні" у вашій службі REST є частиною самого ресурсу, а не метаданих, ви повинні використовувати GET.


2
найкращі речі завжди прості, як і ця відповідь. Вуаля!
Afzal SH

Чудова відповідь! У мене виникає питання: а як щодо використання його як touchкоманди для оновлення кількості перегляду публікацій на сервері? Дані публікації вже отримано за допомогою звичайного /postsдзвінка, тому я просто хочу оновити кількість переглядів після того, як користувач якимось чином взаємодіє з публікацією.
aalaap

1
@aalaap Якщо ви збираєтесь оновити лічильник перегляду для HEADзапитів, то вам слід також зробити це для GETзапитів. Рішення про використання GETабо HEADв кінцевому підсумку залежить від клієнта HTTP. Ваш сервер повинен поводитися однаково для обох типів запитів, за винятком випадків, коли орган відповіді не відповідає HEAD. Щодо того, чи це хороший спосіб реалізувати щось на зразок лічильника перегляду, я не впевнений.
Андре Д

-1 Будь-яка інформація, яку можна назвати, може бути ресурсом. Отже, єдиний локатор ресурсів. Думка про те, що використовувати частину протоколу HTTP, як було розроблено, є "незрозумілим" або "нечистим", є химерною.
Фрейзер

1
@ Сиддхартха, це дуже часто правда, але не завжди. Content-Lengthможе бути пропущено під час використання Transfer-Encoding: chunked. Навіть при Content-Lengthцьому можливо, що сервер може отримати розмір ресурсу та інші метадані, що використовуються в заголовках, не отримуючи фактичний ресурс. Можливо, ці метадані навіть зберігаються в пам'яті для дуже швидкого доступу. Це все дуже конкретно для реалізації.
Андре Д

38

Я знайшов цю відповідь, коли шукав те саме питання, що і запитувач. Я також виявив це на веб- сайті http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html :

Метод HEAD ідентичний GET, за винятком того, що сервер НЕ ПОВИНЕН повертати тіло повідомлення у відповідь. Інформація, що міститься в заголовках HTTP у відповідь на запит HEAD, ДОЛЖНА бути ідентичною інформації, що надсилається у відповідь на запит GET. Цей метод може бути використаний для отримання інформаційної інформації про сутність, що має на увазі запит, без передачі самого суб'єкта-органу. Цей метод часто використовується для тестування гіпертекстових посилань на валідність, доступність та останні модифікації.

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


14

Я сильно заважаю такому підходу.

Служба RESTful повинна поважати семантику дієслів HTTP. Дієслово GET призначене для отримання вмісту ресурсу, тоді як дієслово HEAD не поверне жодного вмісту і може бути використане, наприклад, для того, щоб побачити, чи змінився ресурс, дізнатися його розмір або його тип, перевірити, чи він існує тощо.

І пам’ятайте: рання оптимізація - корінь усього зла.


8

Ваша ефективність навряд чи зміниться, використовуючи HEAD-запит замість GET-запиту.

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


8

Отримати голову + тіло, HEAD отримує тільки голову. Не повинно бути питанням, хто з них швидший. Я не відкидаю вищезазначені відповіді. Якщо ви шукаєте інформацію про META, тоді перейдіть до HEAD, який призначений для цієї мети.


3

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

Це здається дуже заздалегідь спробою оптимізації того, що просто не призведе до значної чи навіть вимірювальної зміни. Справжня різниця полягає у відповідності до REST загалом, який рекомендує використовувати GET для отримання даних.

Моя відповідь "НІ". Використовуйте GET, якщо це має сенс, підвищення продуктивності за допомогою HEAD


Припустимо, вміст становить 100 Мб. Напевно голова буде менше, ніж вміст за розміром. Тепер, коли ми запитуємо цей ресурс методом GET або HEAD, на вашу думку, між ними немає різниці в продуктивності ?!
Мохаммед Афраштех

3
ОП вказала 250 знаків у тілі відповіді. Не 100 Мб. Це зовсім інше питання.
smassey

1

HEAD- запити подібно до GET- запитів, за винятком того, що частина відповіді порожня. Цей вид запиту може використовуватися, коли всі потрібні метадані про файл, але не потрібно транспортувати всі дані файлу.


-1

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

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


GET - це не тільки загадковий «єдиний зайвий байт». Просто все тіло! У випадку великого документа це можуть бути мегабайти.
porfirion
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.