我们运营一个高流量网站。在过去的几天里,我们有几个客户抱怨偶尔会出现停机,而我们无法重现这种情况。我们选择了几台 Web 服务器来接收来自负载均衡器的流量,在调查过程中,我发现所有服务器每秒都丢弃了超过 20 个连接。来自一台服务器的连接示例如下所示:
38452 TIME_WAIT
7815 ESTABLISHED
570 FIN_WAIT2
105 FIN_WAIT1
101 LAST_ACK
36 SYN_RECV
25 CLOSING
4 SYN_SENT
2 CLOSE_WAIT
1 Foreign
我们配置的端口范围目前在所有服务器上都设置为15000 61000
。因此,似乎所有可能的端口都已耗尽,因为已建立或等待关闭的连接数等于 46267。
在调查流量时,我们应该如何处理断开的连接?增加端口范围是否明智?减少关闭连接的等待时间?还是两者都做?做任何一件事都会有潜在的负面影响吗?
答案1
有几种方法可以解决这个问题。
最简单的方法是增加短暂范围,但您已经这样做了,并且显然此解决方案的实施范围存在限制。
另一个解决方案是循环 DNS 并向负载均衡器节点添加多个 IP 地址。有时这并不容易应用(您需要等待获取其他 IP、等待 DNS 传播期等)。
在考虑其他长期解决方案的同时,您可以立即安全地执行两件事:降低 TCP 计时器并打开 tcp_reuse。
tcp_reuse 在负载均衡器上使用非常安全,它的作用是使内核能够重用处于 TIME_WAIT 状态的套接字来建立新连接。要启用它,请在 Linux 机器上运行:
# sysctl -w net.ipv4.tcp_tw_reuse=1
要使其启动持久:
# echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.d/net.ipv4.tcp_tw_reuse.conf
另一个可能有帮助的内核调整参数是:
- net.core.somaxconn(监听队列的大小)
- net.ipv4.tcp_max_syn_backlog(记住的无 ACK 的连接请求数)
另外,您可以将 net.ipv4.tcp_fin_timeout 降低到 1 或 2(如果您的主机是关闭连接的主机,则将套接字保持在 FIN-WAIT-2 状态多长时间)。
希望能帮助到你。