HTTP 请求中的 keep-alive 和 TIME_WAIT 中的 tcp 套接字之间有什么关系 - 它们应该关联吗?
此外,系统和 Web 服务器设置是否应该保持一致server.max-keep-alive-idle = 60
?例如,根据如何减少TIME_WAIT中的套接字数量?在 Linux 中,TIME_WAIT 状态被硬编码为 60 秒(至少对于 Linux 的 Ubuntu/Debain 值而言)。
在 lighttpd 中,默认值server.max-keep-alive-idle = 5
是他们建议的,在高负载下甚至更低。如果 tcp 套接字可用,那么在 5 秒后关闭 http 请求似乎是一种浪费——当然,假设设置确实net.ipv4.tcp_tw_reuse = 1
按照其说明执行。
这个相关问题 -tcp 如何保持连接活跃?[关闭]触及了这个问题,但并没有完全回答我的问题。
答案1
TCP 是第 4 层,HTTP 是第 7 层。
在 HTTP 1.0 中,第 7 层使用 HTTP Keep-Alive 来使用Connection
标头模拟持久连接。
在 HTTP 1.1 中,默认情况下假定连接是持久的,然后仅依靠 TCP 来完成这项工作。请求可以在同一个 TCP 连接中进行流水线传输,然后一方将设置Connection: close
最后一个请求或响应标头,因此双方都知道无法再交换 HTTP 请求,然后连接将关闭。
通常,在 Web 服务器的情况下,状态TIME_WAIT
将是这样的状态:一旦决定主动关闭连接,它就会收到客户端的数据包,并在四向拆卸中FIN
发回最后一个数据包。此后,它会等待:这是一种确保连接已关闭的方法。这就是内核中编译的来源。通过这种方式,我们可以确保在新的连接中,使用相同的 4 元组,不会收到上一个连接中出现的无序数据包。ACK
2 * MSL
60s
你不想改变它。
另一边server.max-keep-alive-idle
是超时,ESTABLISHED
如果超过该时间后没有 HTTP 请求进入,则连接将被视为空闲,并由 Web 服务器主动关闭。正如您现在所理解的,做出此决定后,TCP 断开将发生。
要非常小心tcp_tw_recycle
,如果您的访问者来自广泛的 NAT 网络,那么它可能会导致多个 TCP 连接具有相同的 4 元组,并且时间戳混乱,从而导致服务器端默默丢弃客户端连接尝试。
因此,最好的选择是调整您在 lighttpd 中看到的参数。在系统范围内,您可以安全地降低状态并提高处于和状态的FIN_WAIT2
套接字的存储桶。TIME_WAIT
net.ipv4.tcp_fin_timeout
net.ipv4.tcp_max_tw_buckets