如何减少TIME_WAIT中的套接字数量?

如何减少TIME_WAIT中的套接字数量?

Ubuntu 服务器 10.04.1 x86

我有一台在 nginx 后面带有 FCGI HTTP 服务的机器,它为许多不同的客户端提供大量小型 HTTP 请求。 (高峰时段每秒约有 230 个请求,带标头的平均响应大小为 650 字节,每天有数百万个不同的客户端。)

结果,我有很多套接字挂在 TIME_WAIT 状态(图表是使用下面的 TCP 设置捕获的):

时间的等待

我想减少插座的数量。

除此以外我还能做什么?

$ cat /proc/sys/net/ipv4/tcp_fin_timeout
1
$ cat /proc/sys/net/ipv4/tcp_tw_recycle
1
$ cat /proc/sys/net/ipv4/tcp_tw_reuse
1

更新:有关机器上实际服务布局的一些细节:

客户端-----TCP-socket--> nginx(负载均衡器反向代理)
       -----TCP 套接字--> nginx (工作者)
       --域套接字--> fcgi-软件
                          --单持久-TCP-套接字--> Redis
                          --single-persistent-TCP-socket--> MySQL (其他机器)

我可能也应该将负载均衡器 --> 工作器连接切换到域套接字,但有关 TIME_WAIT 套接字的问题仍然存在 — 我计划很快在另一台机器上添加第二个工作器。在这种情况下将无法使用域套接字。

答案1

您首先要做的一件事就是修复net.ipv4.tcp_fin_timeout=1。这太低了,您可能不应该将其设置为低于 30 的水平。

因为这是在 nginx 后面。这是否意味着 nginx 充当反向代理?如果是这样,那么您的连接就是 2x(一个到客户端,一个到您的 Web 服务器)。您知道这些套接字属于哪一端吗?

更新:
fin_timeout 是它们停留在 FIN-WAIT-2 状态的时间(来自networking/ip-sysctl.txt内核文档):

tcp_fin_timeout - INTEGER
        Time to hold socket in state FIN-WAIT-2, if it was closed
        by our side. Peer can be broken and never close its side,
        or even died unexpectedly. Default value is 60sec.
        Usual value used in 2.2 was 180 seconds, you may restore
        it, but remember that if your machine is even underloaded WEB server,
        you risk to overflow memory with kilotons of dead sockets,
        FIN-WAIT-2 sockets are less dangerous than FIN-WAIT-1,
        because they eat maximum 1.5K of memory, but they tend
        to live longer. Cf. tcp_max_orphans.

我认为你可能只需要让 Linux 将 TIME_WAIT 套接字数量保持在 32k 的上限,然后 Linux 就会回收它们。这个 32k 是本文中提到的关联

此外,我发现 /proc/sys/net/ipv4/tcp_max_tw_buckets 令人困惑。尽管默认值设置为 180000,但当我的系统上有 32K TIME_WAIT 套接字时,无论最大 tw 桶是多少,我都会看到 TCP 中断。

该链接还表明TIME_WAIT状态为60秒,无法通过proc进行调整。

随机有趣的事实:
你可以使用 netstat 查看每个套接字的 timewait 计时器netstat -on | grep TIME_WAIT | less

重用与回收:
这些都很有趣,读起来像重用启用了 time_Wait 套接字的重用,而回收将其置于 TURBO 模式:

tcp_tw_recycle - BOOLEAN
        Enable fast recycling TIME-WAIT sockets. Default value is 0.
        It should not be changed without advice/request of technical
        experts.

tcp_tw_reuse - BOOLEAN
        Allow to reuse TIME-WAIT sockets for new connections when it is
        safe from protocol viewpoint. Default value is 0.
        It should not be changed without advice/request of technical
        experts.

我不建议使用 net.ipv4.tcp_tw_recycle,因为它会导致 NAT 客户端出现问题

也许您可以尝试不同时打开这两个功能,看看效果如何(一次尝试一个,看看它们如何单独工作)?我会使用它们netstat -n | grep TIME_WAIT | wc -l来获得比 Munin 更快的反馈。

答案2

tcp_tw_reuse 相对安全,因为它允许重用 TIME_WAIT 连接。

如果端口耗尽是一个问题,您还可以运行更多在负载均衡器后面监听不同端口的服务。

相关内容