Постоянное соединение HTTP , также называемое HTTP keep-alive или повторное использование соединения HTTP , представляет собой идею использования одногосоединения TCP для отправки и получения нескольких запросов /ответов HTTP, в отличие от открытия нового соединения для каждой пары запрос/ответ. Более новый протокол HTTP/2 использует ту же идею и развивает ее дальше, позволяя мультиплексировать несколько одновременных запросов/ответов по одному соединению.
В HTTP 1.0 соединения всегда должны закрываться сервером после отправки ответа. [1]
Начиная с конца 1995 года [2] разработчики популярных продуктов (браузеров, веб-серверов и т. д.), использующих HTTP/1.0, начали добавлять неофициальное расширение (к протоколу) под названием «keep-alive», чтобы разрешить повторное использование соединения для нескольких запросов/ответов. [3] [4]
Если клиент поддерживает функцию keep-alive, он добавляет к запросу дополнительный заголовок:
Соединение: поддерживать активность
Когда сервер получает этот запрос и генерирует ответ, если он поддерживает keep-alive, то он также добавляет тот же заголовок выше в ответ. После этого соединение не разрывается, а вместо этого остается открытым. Когда клиент отправляет другой запрос, он использует то же самое соединение.
Это будет продолжаться до тех пор, пока клиент или сервер не решат, что разговор окончен, и в этом случае они опустят заголовок "Connection:"
из последнего отправленного сообщения или, что лучше, добавят к нему ключевое слово «close»:
Соединение: близко
После этого соединение закрывается в соответствии с заданными правилами.
Начиная с 1997 года, различные версии спецификаций HTTP/1.1 признавали использование этого неофициального расширения и включали несколько оговорок относительно взаимодействия между HTTP/1.0 (keep-alive) и клиентами/серверами HTTP/1.1. [5]
В HTTP 1.1 все соединения считаются постоянными, если не указано иное. [5] Постоянные соединения HTTP не используют отдельные сообщения keepalive, они просто позволяют нескольким запросам использовать одно соединение. Однако тайм-аут соединения по умолчанию для Apache httpd 1.3 и 2.0 составляет всего 15 секунд [6] [7] и всего 5 секунд для Apache httpd 2.2 и выше. [8] [9] Преимущество короткого тайм-аута заключается в возможности быстрой доставки нескольких компонентов веб-страницы, не потребляя ресурсы для запуска нескольких серверных процессов или потоков слишком долго. [10]
Keepalive затрудняет для клиента определение того, где заканчивается один ответ и начинается следующий, особенно во время конвейерной операции HTTP. [11] Это серьезная проблема, когда ее Content-Length
невозможно использовать из-за потоковой передачи. [12] Для решения этой проблемы в HTTP 1.1 было введено кодирование передачи по частям , которое определяет last-chunk
бит. [13] Бит last-chunk
устанавливается в конце каждого ответа, чтобы клиент знал, где начинается следующий ответ.
Согласно RFC 7230, раздел 6.4, «клиент должен ограничивать количество одновременных открытых подключений, которые он поддерживает к данному серверу». В предыдущей версии спецификации HTTP/1.1 были указаны конкретные максимальные значения, но, по словам RFC 7230, «это оказалось непрактичным для многих приложений... вместо этого... будьте осторожны при открытии нескольких подключений». Эти рекомендации направлены на улучшение времени ответа HTTP и избежание перегрузки. Если конвейеризация HTTP реализована правильно, то нет никакого выигрыша в производительности, который можно было бы получить от дополнительных подключений, в то время как дополнительные подключения могут вызвать проблемы с перегрузкой. [14]
Если клиент не закроет соединение, когда все необходимые ему данные будут получены, ресурсы, необходимые для поддержания соединения открытым на сервере, будут недоступны для других клиентов. Насколько это повлияет на доступность сервера и как долго ресурсы будут недоступны, зависит от архитектуры и конфигурации сервера.
Также может возникнуть состояние гонки , когда клиент отправляет запрос на сервер в то же время, когда сервер закрывает TCP-соединение. [15] Сервер должен отправить клиенту код состояния 408 Request Timeout непосредственно перед закрытием соединения. Когда клиент получает код состояния 408 после отправки запроса, он может открыть новое соединение с сервером и повторно отправить запрос. [16] Не все клиенты будут повторно отправлять запрос, и многие из тех, кто это делает, будут делать это только в том случае, если запрос имеет идемпотентный метод HTTP .
Все современные веб-браузеры, включая Google Chrome , Firefox , Internet Explorer (начиная с версии 4.01), Opera (начиная с версии 4.0) [17] и Safari , используют постоянные соединения.
По умолчанию Internet Explorer версий 6 и 7 использует два постоянных соединения, тогда как версия 8 использует шесть. [18] Время ожидания постоянного соединения истекает через 60 секунд бездействия, что можно изменить через реестр Windows. [19]
В Firefox можно настроить количество одновременных подключений (на сервер, на прокси, всего). Постоянные соединения отключаются через 115 секунд (1,92 минуты) бездействия, что можно изменить с помощью конфигурации. [20]
requests
Библиотека Python содержит requests.Session()
, который устанавливает постоянное HTTP-соединение, тем самым позволяя повторно использовать базовое TCP-соединение, что может привести к значительному повышению производительности. [21]