遭遇短暂的 TCP 端口耗尽

遭遇短暂的 TCP 端口耗尽

我们运营一个高流量网站。在过去的几天里,我们有几个客户抱怨偶尔会出现停机,而我们无法重现这种情况。我们选择了几台 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 状态多长时间)。

希望能帮助到你。

相关内容