Какая связь между keep-alive для HTTP-запроса и tcp-сокетом в TIME_WAIT - должны ли они коррелироваться?
Кроме того, если настройки системы и веб-сервера должны быть согласованы, например server.max-keep-alive-idle = 60
? В соответствии с Как уменьшить количество сокетов за TIME_WAIT? в Linux состояние TIME_WAIT жестко запрограммировано на 60 секунд (по крайней мере, для значений Ubuntu / Debain в Linux).
В lighttpd значение по умолчанию server.max-keep-alive-idle = 5
и они рекомендуют даже ниже при высокой нагрузке. Кажется бесполезным закрывать http-запрос через 5 секунд, если tcp-сокет доступен - конечно, при условии, что параметр net.ipv4.tcp_tw_reuse = 1
делает то, что написано на банке.
Этот связанный вопрос - Как tcp поддерживает соединение? [закрыто] касается вопроса, но не дает мне полного ответа.
TCP - это уровень 4, HTTP уровень 7.
В HTTP 1.0 HTTP Keep-Alive используется на уровне 7 для имитации постоянных соединений с использованием Connection
заголовок.
В HTTP 1.1 соединения считаются постоянными по умолчанию, а затем полагаются на TCP только для выполнения этой работы. Запросы могут быть переданы по конвейеру в одном и том же TCP-соединении, тогда одна сторона установит Connection: close
в заголовках последнего запроса или ответа, поэтому обе стороны знают, что обмен HTTP-запросами невозможен и соединение будет закрыто.
Обычно в случае веб-сервера TIME_WAIT
state будет состоянием, после которого, когда он решил активно закрыть соединение, он получил клиентское FIN
пакет и отправляет последний ACK
назад в четырехстороннем сносе. После этого он ждет 2 * MSL
: это способ убедиться, что соединение закрыто. Вот где 60s
скомпилированный в ядре происходит из. Таким образом, мы уверены, что не будем получать в новом соединении, используя тот же самый кортеж из 4х пакетов, неупорядоченных в результате предыдущего соединения.
Вы не хотите это менять.
С другой стороны server.max-keep-alive-idle
это тайм-аут, после которого ESTABLISHED
соединение будет считаться бездействующим, если не поступит HTTP-запрос, и будет активно закрыто веб-сервером. Когда это решение будет принято, как вы теперь понимаете, произойдет разрыв TCP.
Будьте очень осторожны с tcp_tw_recycle
, если ваши посетители приходят из-за широкой сети с NAT, это может привести к нескольким TCP-соединениям с одними и теми же 4 кортежами с неупорядоченными временными метками, что приведет к молчаливому отбрасыванию попыток клиентских подключений на стороне сервера.
Так что лучший вариант - отрегулировать параметр, который вы видели в lighttpd. Общесистемно, вы можете безопасно опустить FIN_WAIT2
выставить и поднять ковши для розеток в TIME_WAIT
государство с net.ipv4.tcp_fin_timeout
и net.ipv4.tcp_max_tw_buckets
.