HTTP основан на TCP, который управляет отправкой и получением пакетов в правильном порядке и запрашивает повторные передачи, если пакеты были утеряны в середине пути.TCP-соединение начинается с TCP-рукопожатия, состоящего из сообщений SYN
, SYN-ACK
и ACK
, в то время как оно заканчивается сериями FIN
, ACK-FIN
и ACK
, как видно из этого изображения.взято из Wikipedia
Хотя HTTP является протоколом запроса-ответа, открытие и закрытие соединений довольно дорого, и поэтому HTTP / 1.1 позволяет повторно использовать существующие соединения,С заголовком Connection: keep-alive
т.е. вы говорите своему клиенту (т.е. браузеру), чтобы соединение оставалось открытым для сервера.Сервер может иметь несколько тысяч и тысяч открытых соединений одновременно.Во избежание истощения ресурсов сервера соединение обычно своевременно ограничено.Через время ожидания сокета незанятые соединения или соединения с определенными проблемами соединения (нарушенный доступ в Интернет, ...) автоматически закрываются сервером через некоторое предварительно определенное время.
Множество реализаций HTTP, таких как Apache HTTP клиент 4.4 и выше, проверьте состояние соединения только тогда, когда оно собирается его использовать.
Обработка устаревших соединений была изменена в версии 4.4.Ранее код проверял каждое соединение по умолчанию перед повторным использованием.Теперь код проверяет соединение, только если истекшее время с момента последнего использования соединения превышает установленное время ожидания.Время ожидания по умолчанию установлено на 2000 мс ( Источник )
Если, следовательно, какое-то время соединение не использовалось, клиент, возможно, не прочитал ACK-FIN
с сервераи поэтому все еще думают, что соединение открыто, когда оно фактически уже было закрыто сервером некоторое время назад.Такое соединение истекает и обычно называется полузакрытым.Поэтому он может быть собран пулом.
Обратите внимание, что если вы отправляете запросы, включающие заголовок HTTP Connection: close
, соединение должно быть закрыто сразу после того, как клиент получил ответ.
Состояние открытых соединений можно проверить с помощью netstat
, которое должно присутствовать в большинстве современных операционных систем.Недавно мне пришлось проверить одного из наших HTTP-клиентов, управление которым осуществлялось через стороннюю библиотеку, которая неправильно распространяла заголовок Connection: Close
и поэтому приводила к множеству полузакрытых соединений.