今天有个linux服务器一直报Too Many Open Files的异常,导致系统进行网络请求失败,重启应用容器之后恢复正常。
找到了当时的服务器连接监控,发现close_wait状态的连接一直在升高,上升到了10k后就引起应用报错了。因为我们设置的linux的最大的连接数为10240。
在博客园逛了一下,找到了下面的描述
如果我们的服务器TCP连接处于CLOSE_WAIT状态的话,那说明套接字是被动关闭的!
更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/OS/Linux/
因为如果是CLIENT端主动断掉当前连接的话,那么双方关闭这个TCP连接共需要四个packet:
Client ---> FIN ---> Server
Client <--- ACK <--- Server
这时候Client端处于FIN_WAIT_2状态;而Server 程序处于CLOSE_WAIT状态。
Client <--- FIN <--- Server
Server发送FIN给Client,Server 就置为LAST_ACK状态。
Client ---> ACK ---> Server(这步没做)
Client回应了ACK,那么Server 的套接字才会真正置为CLOSED状态。
Server 程序处于CLOSE_WAIT状态,而不是LAST_ACK状态,说明还没有发FIN给Client,那么可能是在关闭连接之前还有许多数据要发送或者其他事要做,导致没有发这个FIN packet。
通常来说,一个CLOSE_WAIT会维持至少2个小时的时间。
了解到这个情况之后,可以定位到应用之所以出现这么多的close_wait的状态,是因为一直在接收合作方发送过来的通知,是有个合作方在发送通知后没有将ACK响应给我们,造成了close_wait状态积压,超过系统设置的最大值而无法再建立连接。
通过修改一下TCP/IP的参数,来缩短这个时间:修改tcp_keepalive_*系列参数有助于解决这个问题。
作者:cnblogs 周蝌蚪