我有一个生产环境(RHEL 7、Java 1.8.0_102-b14),其中运行着许多 JBoss(EAP 7)、Tomcat(8)和独立进程。自我们上次发布 18 天以来,我们所有的流程都在运行。我无法使用 Attach API 连接到 JBoss 和独立进程。下面的 jstack 或简单附加失败。所有这些方法都适用于我的 Tomcat 进程或我启动的任何新进程。
这个问题不会影响任何正在运行的进程,但我们的监控软件不再起作用。
public class Attach{
public static void main( String [] args ) throws Exception {
com.sun.tools.attach.VirtualMachine vm = com.sun.tools.attach.VirtualMachine.attach( args[ 0 ] );
System.out.println( vm.getSystemProperties() );
}
}
我的 tomcat 进程都响应正常,如果我启动任何新的 JBoss 或独立进程,我也可以连接到它们。该进程加载的库集似乎没有任何区别。我的 JBoss 进程的线程数约为 2k,客户端进程以 ~490 运行,tomcat 进程以 ~270 运行。
这是jstack错误:
26346: Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding
我“可以”在本地机器上使用 JMC 进行连接,但响应和加载视图需要几分钟时间。如果我在 jstack 中使用“-F”选项,它会在挂起之前产生以下输出
Attaching to process ID 26346, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.102-b14
Deadlock Detection:
No deadlocks found.
我已经让这个运行了,它还没有附加,但如果有,我会更新帖子。
我计划在本周末发布一个版本,并且能够重新启动我怀疑会修复它的所有进程,但这不是一个长期的解决方案。在下一个版本中,我将尝试将“-XX:+StartAttachListener”标志添加到我们所有的进程中,看看是否有帮助,但可能难以重现。
更新 #1:运行 'kill -3' 确实会转储正在运行的线程,我可以看到 AttachListener 正在一个没有响应的进程上运行:
"Attach Listener" #767 daemon prio=9 os_prio=0 tid=0x00002b88a0008000 nid=0x27d0 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
我没有看到任何死锁的线程。
更新#2
JBoss、Standalone、Tomcat 进程之间存在我没有考虑过的差异。JBoss EAP 7 通过它的管理端口公开了一个 JMX 连接。您可以通过使用引导类路径上的 jboss-client.jar 运行 JMC 来连接到它。对于 Tomcat,我使用以下参数显式公开 jmx,以便我可以远程管理它。启用 jmxremote 是否有可能以某种方式使本地 JMX 附加侦听器保持响应状态?
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=12345
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false