我正在使用Netty(异步nio)以1800连接/分钟的速度在单个linux机器上编写应用程序。如果没有收到应答,则连接会持续几秒钟然后关闭或在20秒后超时。此外,读/写超时为30秒,请求头包含connection=close
。
一段时间(2-3小时)后,我在日志中遇到很多异常,因为由于缺乏资源,Netty无法创建新的连接。
我将limits.conf中打开文件的最大数量增加为:
root hard nofile 200000
root soft nofile 200000
以下是netstat -nat | awk '{print $6}' | sort | uniq -c | sort -n
的输出:
1 established)
1 FIN_WAIT2
1 Foreign
2 TIME_WAIT
6 LISTEN
739 SYN_SENT
6439 LAST_ACK
6705 CLOSE_WAIT
12484 ESTABLISHED
这是ss -s
命令的输出:
Total: 194738 (kernel 194975)
TCP: 201128 (estab 13052, closed 174321, orphaned 6477, synrecv 0, timewait 3/0), ports 0
Transport Total IP IPv6
* 194975 - -
RAW 0 0 0
UDP 17 12 5
TCP 26807 8 26799
INET 26824 20 26804
FRAG 0 0 0
同样ls -l /proc/2448/fd | wc -l
给出约199K。
也就是说,问题是关于ss -s
命令输出中报告的已关闭连接:
1)他们究竟是什么?
2)为什么他们不停地晃来晃去?
3)是否有任何设置(超时或其他)可以帮助将它们保持在合理的限度内?
答案 0 :(得分:1)
1)他们究竟是什么?
它们是从未连接或断开连接且不是close
d。
在Linux中,传出的TCP套接字经历以下各个阶段(大致):
connect()
它到远程端,建立网络连接。shutdown()
读取和写入套接字,关闭网络连接。close()
套接字,内核释放文件描述符。所以那些174K连接ss
报告已关闭的是套接字,这些套接字要么没有超过第1阶段(可能connect()
失败,甚至从未调用过),要么已经过第4阶段,但不是5阶段。有效地,它们是具有底层打开文件描述符的套接字,但没有任何网络绑定(因此netstat
/ ss
列表不显示它们。)
2)为什么他们不停地晃来晃去?
因为没有人打电话给close()
。我会称之为“文件描述符泄漏”或“套接字描述符泄漏”。
3)是否有任何设置(超时或其他)可以帮助将它们保持在合理的限度内?
从Linux的角度来看,没有。您必须在它们上显式调用close()
(或终止拥有它们的进程,以便内核知道它们不再被使用)。
从Netty / Java的角度来看,也许,我不知道。
本质上,它是代码中的错误,或Netty代码(不太可能)或JRE代码中的错误(更不可能)。您应该在应该的时候释放资源。如果您显示代码,也许有人可以发现错误。
答案 1 :(得分:1)
正如Roman正确指出的那样,闭合连接确实存在,并且是从未正确关闭的套接字。 就我而言,我有一些线索可以解决我在下面报告的问题:
1)ss -s
显示了奇怪的值,特别是很多已关闭的连接
2)ls -l /proc/pid/fd | wc -l
显示了很多开放描述符
3)netstat -nat | awk '{print $6}' | sort | uniq -c | sort -n
中的数字与之前的数字不匹配
4)sudo lsof -n -p pid
(罗马建议)显示了很多条目无法识别协议。
在网上浏览我发现了一篇有趣的帖子(https://idea.popcount.org/2012-12-09-lsof-cant-identify-protocol/),它解释了第4点可能意味着什么以及为什么netstat数字不匹配(另见https://serverfault.com/questions/153983/sockets-found-by-lsof-but-not-by-netstat)。
我很惊讶,因为我使用了netty 4.1.x(使用Spring),其中每个连接应该被正确关闭,所以我花了几天时间才弄清楚错误是什么。
微妙的问题出现在netty IO线程中,邮件正文被复制并放入阻塞队列(作为我的代码的一部分)。当队列已满时,这会减慢速度,引入一些延迟并导致我的终端未检测到连接超时,从而导致FD泄漏。
我的解决方案是引入一种池化队列,以防止队列满时的网络请求。
答案 2 :(得分:0)
您仍然没有提供我要求的确切错误消息,但据我所知,问题应该是关于处于CLOSE_WAIT状态的六千五百个连接,而不是那些已关闭的连接' #39;
您没有关闭对等方断开连接的套接字。
那就是说,问题是那些封闭的联系。
什么是封闭连接?您的netstat
显示屏未显示任何已关闭的关联。并且没有证据表明您的资源耗尽问题与封闭连接有关。
1)他们究竟是什么?
他们不是。
2)为什么他们不停地晃来晃去?
他们没有。
3)是否有任何设置(超时或其他)可以帮助将它们保持在合理的限度内?
由于它们不存在,这个问题毫无意义。