ss --processes
和netstat --program
(使用 sudo)都会列出一些到ESTABLISHED
本地端口 6514 的 TCP 连接,这些连接具有非零Recv-Q
值且没有所有者进程(netstat 输出显示-
PID/命令应该在的位置)。
还有其他已建立的到同一本地端口的 TCP 连接,这些连接确实显示了基于 Java(logstash)应用程序的所有者 PID,我希望该应用程序拥有所有这些连接(它拥有 LISTENing 套接字)。这些连接具有空的接收队列。
此外,lsof -i:6514
根本不列出“无主”已建立的 TCP 连接。
ss
在“无主”连接之一的远程端上运行表明它相信连接已建立并且具有空的发送和接收队列。远程端显示连接已建立数周。远程端位于 NAT 之后。
我想了解这些“无主”但已建立的 TCP 连接如何存在,以及它们如何被清理(如果有的话)。
我可以看到,本地端口 6514 的ss --listening
套接字LISTEN
的 Send-Q 为 50,Recv-Q 为 51。我是否可以假设这意味着侦听 Java 进程已达到其并发连接限制,并且是“无主”的原因“建立了联系?
# lsb_release -d
Description: Ubuntu 14.04.1 LTS
# uname -irs
Linux 3.13.0-36-generic x86_64
更新
运行netstat --program --numeric-hosts --numeric-ports --extend
显示“无主”连接的用户不是root
Java 进程用户,并且 INode 是0
。
重新启动 Java 进程一两个小时后,该问题再次出现。这次仅将 LISTEN 套接字 Recv-Q9
与 Send-Q 进行比较50
,并且到本地端口 6514 的 TCP 连接总数为 21,其中有 8 个“无主”连接。
更新2
我现在意识到 LISTEN 套接字上的 Recv-Q 编号与“无主”ESTABLISHED 连接的数量相匹配。我相信这意味着内核已经完成了传入连接上的 TCP SYN/SYN+ACK/ACK 握手,但 Java 进程尚未调用accept()
.
如果我的理解是正确的,我需要调查为什么应用程序不接受新连接。
答案1
我已将这个问题缩小到logstash
JRuby 的 SSL 实现的使用,在两个不同的 Logstash 插件中,在两个不同的 Java 版本上,在不同的机器上,使用不同的客户端,以及有或没有中间 TCP 代理。
在所有情况下,在 Ruby 代码中替换SSLServer
为TCPServer
,并在logstash 之前执行 TLS 卸载可以解决该问题。
JRuby SSL 实现的根本问题,或者它在logstash 上下文中的使用方式,尚未解决。
每个受影响的 Logstash 插件的问题: