Информация о сокете из дампа потока Linux-Java
Анализируя проблему с производительностью, я брал непрерывные дампы потоков каждые 5 секунд и анализировал их с помощью анализатора дампов самурайских потоков. Заметил, что многие потоки находятся в состоянии выполнения с непрерывным сбросом стека во всех случаях. Но я не мог найти, с каким хостом они общаются. Я пытался с помощью команд ss -t -a
, watch ss -tp
а также netstat -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
3 ответа
nid
на самом деле это идентификатор процесса / потока базовой ОС (по крайней мере, для Linux), хотя и в шестнадцатеричной записи. Конвертировать в десятичный pid и использовать
lsof -p pid |grep -Ei 'tcp|socket'
узнать больше об используемых соединениях сокетов. Однако может получиться, что все сокеты открываются основным потоком, и в этом случае дочерние потоки наследуют только несколько (много), поэтому может быть трудно увидеть, к какому потоку он подключен.
Если lsof
не показывает поток основного процесса (кажется, это действительно не так), вам, возможно, придется разрешить поиск в /proc/<pid>/fd
,
tid - идентификатор потока уровня Java, а nid - идентификатор собственного потока. То, на что фактически ссылается nid в разных ОС, несколько сбивает с толку. Я бы порекомендовал подключиться к вашему приложению с помощью такого инструмента, как 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.
Из комментариев и ответов на подобные вопросы. Найдите идентификатор потока, открывающего сокет для сети . Как просмотреть идентификатор потока процесса, открывшего соединение сокета?Кажется, операционная система не отслеживает поток, использующий определенный открытый сокет. Поэтому получить запрошенную вами информацию очень сложно.
В ответе /questions/39868102/kak-prosmotret-identifikator-potoka-protsessa-kotoryij-otkryil-podklyuchenie-k-soketu/39868112#39868112 предлагается (сложный) метод, который требует регистрации системных вызовов с помощью strace с самого начала процесса и, наконец, отладки с помощью gdb процесса, чтобы найти нить.