linux 出现open many files问题 socket未正确关闭

最近网关服务器系统频发soket客户端连接自动断开且 无法再进行通信,开始没有太过深入调查 重启网关既恢复了,但另一天又重复出现,怀疑是不是有线程死锁导致socketserver 服务阻塞,所以仔细分析了下问题, 过程如下:

1. 首先netstat -apn PID |grep port 发现情况:


大量的连接都处于CLOSED_WAIT状态 怀疑服务端没有正常关闭客户端连接。

2.然后jstack pid (jstack 生成当时jvm线程的状态及运行情况) 发现并没有异常信息 ,没有线程处于异常状态。

3.用top -Hp pid 查询进程下所有线程的运行情况(shift+p 按cpu排序,shift+m 按内存排序)

没有CUP使用很高的线程。

综上的调查及连接端口close_wait查阅资料发现 linux 打开文件的句柄/socket是有限制的,通过ulimit -a 发现


最大打开文件句柄数是1024,分析是socket最大连接数超过1024 ,但系统连接的客户端最大600,怎么可能超过1024呢,而且连接出现close_wait 状态,证明连接并未被关闭。

在socket全双工通信过程中有如下几种状态:


   LISTEN - 侦听来自远方TCP端口的连接请求; 
   SYN-SENT -在发送连接请求后等待匹配的连接请求; 
   SYN-RECEIVED - 在收到和发送一个连接请求后等待对连接请求的确认; 
   ESTABLISHED- 代表一个打开的连接,数据可以传送给用户; 
   FIN-WAIT-1 - 等待远程TCP的连接中断请求,或先前的连接中断请求的确认;
   FIN-WAIT-2 - 从远程TCP等待连接中断请求; 
   CLOSE-WAIT - 等待从本地用户发来的连接中断请求; 
   CLOSING -等待远程TCP对连接中断的确认; 
   LAST-ACK - 等待原来发向远程TCP的连接中断请求的确认; 
   TIME-WAIT -等待足够的时间以确保远程TCP接收到连接中断请求的确认; 
   CLOSED - 没有任何连接状态;


原因分析:在TCP/IP协议中,TCP提供可靠的连接服务,连接采用三次握手建立,由于连接是全双工的,关闭连接时,每个方向都要单独关闭,连接拆除需要发送来回共发送四个包,因此叫做四次挥手,任何一个过程中途没接受到消息都会停留在某一个状态,很明显目前大部分连接停留在close_wait 状态,等待超时读取时间关闭,一旦超时过长或未设置  并发量过大就容易导致客户端连接数过大,超过linux 设置的open_files ,就导致端口被占满,发生 many open files无法通信。

解决办法:

a) 修改linux open files 参数为65535

 查询linux open file参数命令 :ulimit -a

 修改参数方法:

 1)ulimit -n 65536 修改当前会话的 open files 参数 只能临时改动参数  重新登录参数失效

 2)使用ROOT 用户登  修改文件/etc/security/limits.conf 添加:

xxx - nofile  65535
xxx 是一个用户,如果是想所有用户生效的话换成 * ,设置的数值与硬件配置有关,别设置太大了。

b) 设置socket读取超时关闭时间或者更短 socket.setTimeout(3000);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章