Связь между состоянием tcp TIME_WAIT и HTTP keep-alive
Какова связь между 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 поддерживает соединение? [закрыто] затрагивает вопрос, но не полностью отвечает на него для меня.
1 ответ
TCP это уровень 4, HTTP уровень 7.
В HTTP 1.0 HTTP Keep-Alive используется на уровне 7 для имитации постоянных соединений с использованием Connection
заголовок.
В HTTP 1.1 соединения по умолчанию считаются постоянными, а затем полагаются на TCP только для выполнения этой работы. Запросы могут быть переданы по конвейеру в том же TCP-соединении, тогда одна сторона установит Connection: close
в заголовках последнего запроса или ответа, так что обе стороны знают, что обмен HTTP-запросом больше невозможен, и соединение будет закрыто.
Обычно в случае веб-сервера TIME_WAIT
состояние - это состояние, после которого, решив активно закрывать соединение, он получил 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
,