调试 JConsole 连接失败

27

我有一个部署在远程Resin服务器上的Web应用程序,并且已经启用了JMX。

我可以通过telnet连接到远程服务器,例如:

franz@see:/tmp$ telnet <remote-ip> 5555
Trying <remote-ip>...
Connected to <remote-ip>.
Escape character is '^]'.
��sr5javax.management.remote.message.HandshakeBeginMessage�,���6profilestLjava/lang/String;Lversionq~xppt1.0^]

telnet> q
Connection closed.

但是我无法使用JConsole连接它

$JAVA_HOME/bin/java -cp $JAVA_HOME/lib/jconsole.jar:$JAVA_HOME/lib/tools.jar:pm-common/lib/jmxremote_optional-1_0_1_3.jar sun.tools.jconsole.JConsole service:jmx:jmxmp://<remote-ip>:5555

我已经尝试了以下几个Java版本,但在两个实例上都出现了“连接失败”的错误。

## where JAVA_HOME=/opt/java/64/jdk1.5.0_22
java version "1.5.0_22"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_22-b03)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_22-b03, mixed mode)

## where JAVA_HOME=/opt/java/64/jdk1.6.0_17
java version "1.6.0_17"
Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
Java HotSpot(TM) 64-Bit Server VM (build 14.3-b01, mixed mode)

你们有没有想法如何调试这个问题(即找出问题所在)?

9个回答

41

请确保您正在运行应用程序时设置了以下Java属性

-Dcom.sun.management.jmxremote.port=9005
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

现在尝试连接。如果您想调试此问题,可以使用以下命令运行JConsole。

jconsole -J-Djava.util.logging.config.file=path_to_logging.properties_for_jconsole

以下是logging.properties文件的内容

Logging.properties

handlers = java.util.logging.ConsoleHandler


.level = INFO

java.util.logging.ConsoleHandler.level = FINEST

java.util.logging.ConsoleHandler.formatter = \

java.util.logging.SimpleFormatter

// Use FINER or FINEST for javax.management.remote.level - FINEST is

// very verbose...

javax.management.level = FINEST

javax.management.remote.level = FINER

运行jconsole后,会弹出一个单独的窗口显示日志。


3
嘿!缺失属性'java.rmi.server.hostname'怎么办?请查看此帖子:http://www.gubatron.com/blog/2010/11/21/jconsole-connection-failed-retry-solved-java-jmx/!!希望能有所帮助! - Victor
还要确保密码文件受到读取保护!即只有用户可以读取它 - 使用chmod 600实现此目的。 - Mafro34
1
为什么每个人都在谈论远程连接?我正在尝试本地连接,但仍然无法工作。"连接失败:重试?到15663的连接未成功。" 为什么?日志在哪里?错误在哪里?真是一个笑话。 - JeneralJames
我需要通过SSL隧道访问JMX端口。对我来说,必须添加"java.rmi.server.hostname"属性,并将其设置为127.0.0.1,而不是真实的机器IP!一旦我将其设置为127.0.0.1,它就可以通过隧道正常工作了... - riskop
我需要通过SSL隧道访问JMX端口。对我来说,添加"java.rmi.server.hostname"属性是必要的,并且必须将其设置为127.0.0.1,而不是真实的机器IP!一旦我将其设置为127.0.0.1,它就可以通过隧道正常工作了... - undefined

29

10

这最终让我成功了:增加这个选项:-Djava.rmi.server.hostname=<在jvm运行的ip地址>

因此,在远程机器上使用vm参数打开jconsole时,必须启动远程机器上的jvm。

 -Dcom.sun.management.jmxremote.authenticate=false  -Dcom.sun.management.jmxremote.port=<port> -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=<ip address>

整个过程在这里列出。


1
这对我也起作用了。看起来当您使用NAT时,需要指定服务器地址。 - hacket
经过长时间的搜索,当我从不同的机器连接时,添加-Djava.rmi.server.hostname=<ip地址>终于对我有用了。以下是完整的参数:java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=<IP>
com.example.Main
- user1102967

3

当我通过cygwin启动Java进程时,遇到了同样的问题。JConsole无法连接。但是当我通过win7-cmd启动它时,一切都如预期般工作。


1
我不确定这是否有帮助,但也许你应该使用JDK二进制文件夹中的jconsole二进制文件来启动控制台,而不是使用未记录(并且可能会更改)的sun.*类。

还是不起作用。而且我也不知道如何调试这个问题。 - Franz See
这篇文章(http://blogs.sun.com/jmxetc/entry/troubleshooting_connection_problems_in_jconsole)解释了常见的连接问题,可能会有所帮助。如果仍然无法解决,请查看/发布调试日志。 - qwerty

1

如果您的应用程序正在运行JDK 1.6,则应该能够连接它。如果它使用早于1.6的JDK,则运行它时请指定以下JVM参数。

-Dcom.sun.management.jmxremote


无法工作(在JDK1.5和JDK1.6上都尝试过)。而且我也不知道如何调试它。 - Franz See

1

我遇到了类似的问题,远程机器在防火墙后面,防火墙阻止了由-Dcom.sun.management.jmxremote.port和RMI46924定义的端口。在允许连接这些端口后,我成功地连接了。


在我的情况下,RMI端口是43702,我通过使用logging.properties进行调试找到了这一点。 - Panu Haaramo

0
对我来说,我正在使用本地进程连接,并且遇到了与 OP 相同的问题。 我误解的是,“如果是本地连接,则无法拒绝连接,对吧?” 不一定。
另一位用户 JeneralJames 在 samarth 的答案评论中提到了我遇到的完全相同的症状。
解决问题的方法是断开 VPN 连接(或在连接 VPN 时启用局域网访问 - 这是我的 VPN 设置的非默认配置)。
我通过运行 rogerdpack 建议的 jconsole -debug 发现了问题,并显示了一个我不期望的 IP 地址,尽管是与本地进程的连接。当时我的 VPN 设置禁止在整个本地网络上建立连接,因此 Java 正在查找本地 IP,获取其值,但由于 VPN 配置的限制,该 IP 不允许连接,因此“本地连接”被拒绝。
显然, jconsole(或任何其他使用 JMX 应用程序的 MBeans)即使针对本地连接也会默认使用此错误的 IP。希望这可以帮助其他人,我已经花费了三天时间浏览多个 stackoverflow 线程和 Java 文档,直到发现了 -debug 选项。

0

如果您正在访问防火墙后面的机器,则需要打开JMX和RMI端口。
在这种情况下,最好强制指定RMI的值,而不是依赖于自动分配的值。
在我的情况下,我正在尝试访问Tomcat,因此我必须执行以下操作:

#!/bin/sh
CATALINA_OPTS="$CATALINA_OPTS -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv4Addresses=true -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8008 -Dcom.sun.management.jmxremote.rmi.port=8007 -Dcom.sun.
management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"

然后

firewall-cmd --zone=public --add-port=8008/tcp --permanent
firewall-cmd --zone=public --add-port=8007/tcp --permanent
firewall-cmd --reload

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接