调整内核参数
net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1
这两个参数可以让 tcp 连接回收、再利用。
摘录
『HTTP 权威指南』page 90 关于 TIME_WAIT 的解释:
TIME_WAIT 端口耗尽是很严重的性能问题,会影响到性能基准,但在现实中相对较少出现。大多数遇到性能基准问题的人最终都会碰到这个问题,而且性能都会变得出乎意料的差,所以这个问题值得特别关注。
当某个 TCP 端点关闭 TCP 连接时,会在内存中维护一个小的控制块,用来记录最近所关闭连接的 IP 地址和端口号。这类信息只会维持一小段时间,通常是所估计的最大分段试用期的两倍(称为2MSL,通常为2分钟)左右,以确保在这段时间内不会创建具有相同地址和端口号的新连接。实际上,这个算法可以防止在2分钟内创建、关闭并重新创建2个相同 IP 地址和端口号的连接。
现在高速路由器的使用,是的重复分组几乎不可能在连接关闭的几分钟之后,出现在服务器上。有些操作系统会将2MSL 设置为一个较小的值,但修改此值时要特别小心。分组确实会被复制,如果来自之前连接的复制组插入具有相同连接值的新 TCP 流,会破坏 TCP 数据。
2MSL 的连接关闭延迟通常不是什么问题,但在性能基准环境下就可能会成为一个问题。进行性能基准测试时,通常只有一台或几台用来产生流量的计算机连接到某系统中去,这样就限制了连接到服务器的客户端 IP 地址数。而且,服务器通常会在 HTTP 默认端口80上进行监听。用 TIME_WAIT 防止端口号重用时,这些情况也限制了可用的连接值组合。
在只有一个客户端和一台 web 服务器的异常情况下,构建一条 TCP 连接的4个值:
<源 IP 地址,源端口,目标 IP 地址,目标端口>
其中的3个都是固定的——只有源端口号可以随意改变:
<client-IP, source-port, server-IP,80>
客户端每次连接到服务器上去时,都会获得一个新的源端口,以实现连接的唯一性。但由于可用源端口的数量有限(比如60000个),而且在2MSL(比如,120s)内连接是无法重用的,连接率就被限制在了:60000/120 = 500次/s. 如果再不断进行优化,并且服务器的连接率不超过500次/s, 就可以确保不会遇到 TIME_WAIT 端口耗尽的问题。要修正这个问题,可以增加客户端负载生成器的数量,或者确保客户端和服务器在循环使用几个虚拟 IP 地址以增加更多的连接组合。
即使没有遇到端口耗尽的问题,也要特别小心有大量连接出于打开状态的情况,或为处于等待状态的连接分配了大量控制块的情况。在有大量打开连接或控制块的情况下,有些操作系统的速度回严重减缓。