Что значит connection keep alive

Как интерпретировать «соединение: keep-alive, close»?

из того, что я понимаю, HTTP-соединение может быть либо keep-alive или close .

Я отправил HTTP-запрос на сервер:

по сути, я считаю, что сервер прослушивается, потому что ответ типа keep-alive, close неоднозначно.

, как приемник как дескриптор такое сообщение? Должны ли мы интерпретировать это значение заголовка keep-alive или close ?

4 ответов

TL; DR: Chrome интерпретирует этот заголовок ответа как keep-alive и поддерживать постоянное соединение, пока Firefox закрывает каждое соединение.

я наткнулся на этот вопрос, когда пытался оптимизировать время загрузки страницы для моего сайта.

в указанном RFC я ничего не нашел о том, как несколько записей в Connection заголовок может быть правильно обработаны. Мне показалось, что реализация может выбрать один из двух вариантов:

  1. если есть несколько записей, вы можете выбрать, что подходит лучше всего для ваших нужд
  2. если есть close внутри, вы можете закрыть соединение после передачи

Итак, мне нужно выяснить. Давайте проведем более глубокое исследование:

Я заметил, что Chrome всегда отправлял запрос HTTP/1.1 с Connection: keep-alive и моя конфигурация по умолчанию Apache всегда отвечала с . Поэтому я начал расследование и . взглянул на сегменты TCP с Wireshark.

Chrome должен получить 14 элементов для отображения веб-сайта, в основном статические вещи, такие как изображения или css-файлы. И это заняло 14 TCP-соединений, и это заняло много времени (примерно 1,2 секунды). После каждого запроса изображения (например) появляется TCP-сегмент с FIN флаг установлен в 1.

так что насчет Chrome против Firefox? Chrome, похоже, имеет максимальное количество одновременных подключений к одному сервер 6. Firefox имеет более детальную конфигурацию и различает постоянные (maxium 6, см. about:config) и непостоянные (максимальные числа сильно отличались в разных источниках). Но подождите. И Chrome, и Firefox отправляют заголовки запросов HTTP / 1.1 с Connection: keep-alive , поэтому оба должны быть ограничены 6 (так как это запрос на открытие постоянного соединения).

Я решил попробовать простой трюк и добавил следующие строки в мой .htaccess в корне web папка:

теперь я снова взглянул на сегменты TCP: теперь было только 9 подключений от Chrome к моему серверу и только 3 с FIN флаг установлен в 1. Похоже, этот трюк сработал. Но почему были те 3 соединения, которые закрыли соединение после передачи данных? Это были запросы PHP, как HTTP-заголовок X-Powered-By: PHP/5.4.11 подтвердил.

а как насчет Firefox? Были еще эти 14 запросов!

как это исправить и заставить процессы fcgi работать с keep-alive тоже?

Я добавил следующие строки в раздел virtualhost httpd.конфигурации:

и удалил те, которые добавлены в .htaccess . Теперь сервер не отправляет никаких запутанных — Connection: keep-alive, close , но только Connection: keep-alive и все работает отлично!

вывод:

заголовок с набором полей подключения к

будет интерпретироваться Chrome как keep-alive в то время как Firefox, похоже, закрывает каждое соединение. Как представляется, это зависит от фактического осуществления.

поэтому, если вы хотите реализовать клиент для обработки заголовков ответов, содержащих Connection: keep-alive, close , я бы предложил попробовать использовать keep-alive, если вам нужно более одного запроса. Самое худшее, что может случиться: сервер закроет соединение и вам нужно подключиться снова (это именно другой вариант бы!)

Источник

Http запросы — мы все это делаем неправильно

В проекте, над которым я работаю, мы используем огромное количество сторонних библиотек. Многие из них — адаптеры для различных сервисов. Что их объединяет, это то, что они работают с сетью. Json поверх http, soap поверх http, какие-то свои протоколы поверх http. Т.е. все так или иначе используют http. И как ни удивительно, мало кто из них пользуется преимуществами его последней версии. Я не поленился заглянуть в википедию, прошло ровно 14 лет как была принята спецификация http 1.1. И потому я решил обратиться с призывом:

Да, речь пойдет о keep alive. Суть в том, что, начиная с http 1.1, клиент и сервер могут договориться не закрывать установленное tcp-соединение после завершения запроса, а переиспользовать его для следующих запросов. Это нужно потому, что на установку соединения требуется время. Иногда это время больше, чем время самого запроса. И если все серверы уже давным-давно такую возможность поддерживают, а все браузеры и большинство других клиентов её используют, то у разработчиков различных библиотек для популярных языков программирования здесь почему-то пробел.
Рассмотрим простой код на PHP, который последовательно делает 10 запросов к одному серверу:

Это каркас 95% библиотек, обращающихся к сторонним ресурсам. Опция CURLOPT_VERBOSE позволяет видеть в консоли все, что делает библиотека curl во время выполнения скрипта. И самые интересные строчки будут повторяться все 9 запросов (кроме первого):

Как видите, curl оставляет соединение после запроса открытым, но мы его тут же закрываем. Результат печален: 10 запросов создают 10 соединений, скрипт выполняется не менее 17 секунд.

Это говорит о том, что сам curl знаком с http 1.1, а мы мешаем ему нормально работать. Но исправить это очень просто:

Мы просто вынесли создание и удаление дескриптора из цикла, и картина при следующем запуске поменялась:

А время работы сократилось до 5,5 секунд. Конечно, тут я намеренно обращаюсь к статическому файлу. В реальных условиях некоторое время займет формирование запроса. Плюс, если вы используете http без ssl, время соединения будет немного меньше. Тем не менее, постоянные соединения в любом случае дают существенный выигрыш.

Я провел несколько экспериментов, измеряя время, необходимое на 10 запросов по протоколам http и https с использованием отдельных соединений и keep-alive для файлов разного размера с разными пингами до сервера. Брался лучший результат за 5-6 измерений.

evernote.com/favicon.ico, Пинг ≈ 200 ms, размер 27054 байт.

Reconnect Keep-Alive Ratio
http 10 5 2x
https 17 5,5 3,1x

twitter.com/favicon.ico, Пинг ≈ 200 ms, размер 1150 байт.

Reconnect Keep-Alive Ratio
http 4,3 2,5 1,7x
https 8,5 2,7 3,1x

yandex.st/lego/_/pDu9OWAQKB0s2J9IojKpiS_Eho.ico, Пинг ≈ 17 ms, размер 1150 байт.

Reconnect Keep-Alive Ratio
http 0,33 0,17 1,9x
https 0,8 0,2 4x

Цифры говорят сами за себя. Но прелесть даже не в них, а в том, что добиться этого очень просто. Все что вам нужно сделать в случае использования curl — перенести вызов curl_init() из метода, который делает запрос, в конструктор класса (вот один и другой пример, где это легко можно сделать). При этом curl_close() можно выкинуть совсем, ресурсы и так освободятся при завершении запроса. Curl сам держит пул соединений для каждой пары хост и порт, к которым вы обращаетесь, и переоткрывает закрытые соединения.

На самом деле речь, конечно, не про curl и php. В каждом языке можно найти библиотеку, реализующую такой же пул. Например, для python это прекрасная urllib3 — на основе которой построена популярная библиотека requests. С ней дела обстоят точно так же, как с curl в php, её очень просто использовать, но не все это делают правильно. И я бы хотел показать несколько примеров, как это можно исправить. Вот так я сделал поддержку постоянных соединений в клиенте stripe. После этого функциональные тесты в нашем проекте стали выполняться в 2 раза быстрее, хотя они не только со страйпом обращались, конечно. А так я пофискил нашу библиотеку pyuploadcare. В обоих случаях все что нужно было сделать — заменить вызовы функций requests.request() на вызовы методов объекта session , созданного заранее.

Надеюсь, мне удалось убедить вас в необходимости обращать на это внимание при разработке библиотек, и показать, насколько это просто реализуется.

Источник

Как работает http keep-alive?

Keep-alives были добавлены к HTTP, чтобы в основном уменьшить значительные издержки быстрого создания и закрытия сокетов для каждого новый запрос. Ниже приводится краткое описание того, как это работает в HTTP 1.0 и 1.1:

HTTP 1.0 спецификация HTTP 1.0 действительно не вникает в то, как Keep-Alive должен работать. В основном, браузеры, которые поддерживают Keep-Alive добавляет дополнительный заголовок к запросу, как:

подключение: Keep-Alive, когда сервер обрабатывает запрос и генерирует ответ, он также добавляет заголовок ответа: Соединение: Keep-Alive когда это сделано, соединение гнезда не закрыта, как раньше, но открыта после отправки ответа. Когда клиент отправляет другой запрос, он повторно использует то же соединение. Этот соединение будет использоваться повторно до тех пор, пока клиент или сервер решает, что разговор окончен, и один из них падает соединение.

приведенное выше объяснение здесь. Но я ничего не понимаю!—3—>

когда это сделано, соединение сокета не закрыто как раньше, но открыт после отправки ответа.

Как я понимаю, мы просто отправляем tcp-пакеты для запросов и ответов, как это socket connection помогает и как это работает? Мы все еще должны отправлять пакеты, но как он может каким-то образом установить постоянный связь? Это кажется таким нереальным.

4 ответов

существуют накладные расходы при установлении нового TCP-соединения (DNS-запросы, TCP-рукопожатие, SSL/TLS рукопожатие и т. д.). Без keep-alive каждый HTTP-запрос должен установить новое TCP-соединение, а затем закрыть соединение после отправки/получения ответа. Keep-alive позволяет существующему TCP-соединению повторно использоваться для нескольких запросов / ответов, тем самым избегая всех этих накладных расходов. Именно это делает связь «постоянной».

в HTTP 0.9 и 1.0, по умолчанию сервер закрывает конец TCP-соединение после отправки ответа клиенту. Клиент должен закрыть свой конец TCP-соединения после получения ответа. В HTTP 1.0 (но не в 0.9) клиент может явно попросить сервер не закрывать свой конец соединения, включив Connection: keep-alive заголовок в запросе. Если сервер согласен, он включает в себя Connection: keep-alive заголовок в ответе и не закрывает его конец соединения. Затем клиент может повторно использовать то же TCP-соединение чтобы отправить свой следующий запрос.

в HTTP 1.1, keep-alive — это поведение по умолчанию, если клиент явно не просит сервер закрыть соединение, включив Connection: close заголовок в своем запросе, или сервер решает включить Connection: close заголовок в своем ответе.

давайте проведем аналогию. HTTP состоит в отправке запроса и получении ответа. Это то же самое, что задать кому-то вопрос и получить ответ.

проблема в том, что вопрос и ответ должны проходить через сеть. Для связи через сеть используется TCP (сокеты). Это похоже на использование телефона, чтобы задать вопрос кому-то и получить ответ этого человека.

HTTP 1.0 состоит, когда вы загружаете страницу, содержащую 2 изображения для например, в

  • позвонить
  • попросите страницу
  • попадаешь на страницу
  • завершить телефонный звонок
  • позвонить
  • попросите первое изображение
  • получить первое изображение
  • завершить телефонный звонок
  • позвонить
  • попросите второе изображение
  • получить второе изображение
  • завершить телефонный звонок

телефонный звонок и для ее завершения требуются время и ресурсы. Контрольные данные (например, номер телефона) должны передаваться по сети. Было бы более эффективно сделать один телефонный звонок, чтобы получить страницу и два изображения. Это то, что keep-alive позволяет делать. С keep-alive, выше становится

  • позвонить
  • попросите страницу
  • попадаешь на страницу
  • попросите первое изображение
  • получить первое изображение
  • попросите второй изображение
  • получить второе изображение
  • завершить телефонный звонок

это действительно сетевой вопрос, но это может быть уместно здесь в конце концов.

путаница возникает из-за различия между пакетно-ориентированными и потоковыми соединениями.

Интернет часто называют сетью» TCP/IP». На низком уровне (IP, Internet Protocol) интернет ориентирован на пакеты. Хосты отправляют пакеты другим хостам.

однако поверх IP у нас есть TCP (протокол управления передачей). Все назначение этого слоя интернет-это скрыть пакетно-ориентированный характер базового носителя и представить соединение между двумя хостами (хостами и портами, чтобы быть более правильным) как поток данных, подобный файлу или каналу. Затем мы можем открыть сокет в API ОС, чтобы представить это соединение, и мы можем рассматривать этот сокет как файловый дескриптор (буквально FD в Unix, очень похожий на файловый дескриптор в Windows).

большинство остальных протоколов Интернет-Клиент-Сервер (HTTP, Telnet, SSH, SMTP) поверх протокола TCP. Таким образом, клиент открывает соединение (сокет), записывает свой запрос (который передается как один или несколько карманов в базовом IP-адресе) в сокет, считывает ответ из сокета (и ответ может содержать данные из нескольких IP-пакетов), а затем. Тогда выбор заключается в том, чтобы сохранить соединение открытым для следующего запроса или закрыть его. Pre-KeepAlive HTTP всегда закрывал соединение. Новые клиенты и серверы могут держать его открытым.

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

небольшим недостатком может быть то, что сервер теперь должен сообщить клиенту, где заканчивается ответ. Сервер не может просто отправить ответ и закрыть соединение. Он должен сказать клиенту:»прочитайте 20KB, и это будет конец моего ответа». Таким образом, размер ответа должен быть известен заранее, и сообщается клиенту в рамках протокола более высокого уровня (например, Content-Length: в HTTP). Кроме того, сервер может отправить разделитель, чтобы указать конец ответа — все зависит от протокола выше TCP.

вы можете понять это так:

HTTP использует TCP в качестве транспорта. Перед отправкой и получением пакетов через TCP,

  1. клиент должен отправить запрос на подключение
  2. сервер отвечает
  3. передача данных осуществляется
  4. соединение закрывается.

однако, если мы используем функцию keep-alive, соединение не закрывается после получения данных. Соединение остается активным.

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

Источник

Читайте также:  Что значит опухоль разрушается
Оцените статью