【问题标题】:Socket information from Linux-Java thread dump来自 Linux-Java 线程转储的套接字信息
【发布时间】:2016-01-07 13:30:18
【问题描述】:

在分析性能问题时,我每 5 秒进行一次连续线程转储,并使用 samurai 线程转储分析器进行分析。请注意,许多线程处于可运行状态,并且在所有情况下都连续出现以下堆栈转储。但我找不到他们正在与哪个主机通信。我尝试使用命令ss -t -awatch ss -tpnetstat -A inet -p,但无法将它们的结果与线程相关联。任何想法?提前致谢。

Thread dump 2/5 "TP-Processor125"   prio=5 tid=0x25756 nid=0x649c RUNNABLE (JNI Native Code) - stats: cpu=828 blk=-1 wait=-1      java.lang.Thread.State: RUNNABLE      
     at java.net.SocketInputStream.socketRead0(Native Method)      
     at java.net.SocketInputStream.read(SocketInputStream.java:152)      
     at java.net.SocketInputStream.read(SocketInputStream.java:122)      
     at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)      
     at java.io.BufferedInputStream.read1(BufferedInputStream.java:275)      
     at java.io.BufferedInputStream.read(BufferedInputStream.java:334)      
     at org.apache.jk.common.ChannelSocket.read(ChannelSocket.java:628)
     at org.apache.jk.common.ChannelSocket.receive(ChannelSocket.java:566)
     at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:693)
     at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:898)
     at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690)
     at java.lang.Thread.run(Thread.java:745)      Locked synchronizers: count = 0

【问题讨论】:

  • 这是用于服务器还是客户端?例如。服务器套接字还是客户端套接字?
  • 抱歉,我没有该信息。我所拥有的只是从服务器获取的线程转储。它与许多接口进行交互,包括 DB、Webserver ... etc.It 说“SocketInputStream.read”。会不会是服务器套接字?
  • 转储有多大?您可以上传到 Github 或其他共享吗?
  • 我提供的只是线程转储。它只是在进行转储时线程正在做什么的堆栈跟踪。

标签: java linux sockets thread-dump


【解决方案1】:

nid 实际上是底层操作系统的进程/线程 ID(至少对于 Linux),尽管是十六进制表示法。转换为十进制 pid 并使用

lsof -p pid |grep -Ei 'tcp|socket'

了解有关使用的套接字连接的更多信息。但可能结果是,所有套接字都由主线程打开,在这种情况下,子线程只继承几个(许多),因此可能很难看到它连接到哪个线程。

如果lsof 没有显示主进程的线程(似乎确实没有),您可能必须下决心查看/proc/<pid>/fd

【讨论】:

  • 这样做了,但没有得到结果。不确定 lsof 只接受进程 ID 而不是线程 ID。另外,当我将十六进制转换为十进制并发出 'ps -eLf | grep 25781' 获取线程详细信息,但没有得到任何结果。这里 25781 是十六进制 nid(0x64b5) 的十进制值。
【解决方案2】:

tid 是 Java 级别的线程 id,nid 是本机线程 id。 nid 在不同操作系统上实际指的是somewhat confusing。我建议使用 Visual VM 等工具连接到您的应用程序并记下应用程序的 PID。获得 PID 后,请尝试以下命令:

sudo netstat -nlpt

这应该会为您提供如下信息(带有远程/本地地址以及 PID 和程序名称):

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.1.1:53            0.0.0.0:*               LISTEN      1144/dnsmasq    
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      661/cupsd       
tcp6       0      0 ::1:631                 :::*                    LISTEN      661/cupsd

这应该告诉您从您的 Java 程序打开了哪些连接。

【讨论】:

  • 谢谢你 MajoJojo。但是这种方法再次在 pid 级别进行讨论。我想知道的是线程级别。 Pid 有很多线程,线程转储显示每个线程在做什么。在 unix 中, ps -eLf 命令列出线程和进程。如果我们知道进程 ID,我们可以运行 'ps -eLf | grep pid' 了解线程列表。在我的线程转储中,许多线程正在从套接字读取数据,但我无法确定那个套接字是什么。希望我的问题很清楚。
猜你喜欢
  • 1970-01-01
  • 2019-04-24
  • 1970-01-01
  • 2015-10-15
  • 1970-01-01
  • 2010-10-31
  • 1970-01-01
  • 2011-11-26
  • 2020-03-28
相关资源
最近更新 更多