太多已建立的连接处于打开状态

太多已建立的连接处于打开状态

我有一台(可能很旧的)CentOS 4.5 服务器,里面运行着自定义的 java 应用程序。

我发现应用程序运行一段时间后崩溃了,发现它正在处理 1024 个连接,并在崩溃时尝试打开一个以上的套接字。

事实上,如果我检查的话,ulimit -n我可以确认它是 1024,所以应用程序正在关闭,因为它没有更多的可用文件描述符。

令我困扰的是,有数百个明显处于非活动状态的连接,处于“已建立”状态,所有连接都来自相对较少的 IP(约 200 个),并且随着时间的推移和客户端的连接,它们往往会累积起来,就像我看到的这些正在运行的连接一样netstat -nato

tcp        0      0 ::ffff:10.39.151.20:10000   ::ffff:78.152.97.98:12059   ESTABLISHED off (0.00/0/0)
tcp        0      0 ::ffff:10.39.151.20:10000   ::ffff:78.152.97.98:49179   ESTABLISHED off (0.00/0/0)
tcp        0      0 ::ffff:10.39.151.20:10000   ::ffff:78.152.97.42:45907   ESTABLISHED off (0.00/0/0)

我知道这不是 DOS 攻击,连接是合法的,但是客户端连接并与服务器进行短暂的数据交换后似乎不会关闭...而且速度很慢,因为它们是由 200 个客户端(计算不同的 IP)生成的...

我是否应该调查一些奇怪的应用程序错误(可能是在 jre 1.6 上),或者深入研究 CentOS 网络配置?我不知道还应该看什么。

提前致谢,任何提示都值得赞赏!

答案1

假设 1:您的应用程序位于防火墙后面,防火墙会在给定的时间后丢弃空闲的 TCP 连接。

当客户端尝试再次使用此连接时,它会发现该连接没有响应,于是便会丢弃它并启动一个新连接。

对于服务器来说,由于 TCP 连接没有保持活动计时器,因此无法知道连接是否无效,并且它将无限期地保持打开状态。

为了证明:对一个连接进行长时间运行的 tcpdump,以显示该连接在给定的时间后变为未使用状态。

解决方案:

  • 更改代码以在 tcp 套接字上使用 keepalive,并且(可选,为了获得最佳性能)将 keepalive 计时器设置为低于防火墙 tcp-idle 计时器
  • 将防火墙 tcp-idle 计时器更改为高于客户端最大功能空闲时间的值。这很可能是防火墙上的全局设置,因此您的安全管理员可能不太愿意这样做。

相关内容