Java jconsole jmx连接失败

5
我正在尝试将jconsole连接到由以下方式调用的jvm:
java \
-Djava.util.logging.config.file=./logging.properties \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.port=12700 \
-cp . Sleep

然后我尝试使用以下命令启动jconsole:

jconsole -J-Djava.util.logging.config.file=./logging.properties

logging.properties 文件包括:

sun.rmi.level=FINEST

在打开到端口12700的套接字之后,rmi似乎会尝试在另一个端口上建立连接:

FINER: [javax.management.remote.rmi.RMIConnector: jmxServiceURL=service:jmx:rmi:///jndi/rmi://10.40.243.12:12700/jmxrmi] connecting...
Jan 5, 2012 2:30:42 PM RMIConnector connect
FINER: [javax.management.remote.rmi.RMIConnector: jmxServiceURL=service:jmx:rmi:///jndi/rmi://10.40.243.12:12700/jmxrmi] finding stub...
Jan 5, 2012 2:30:43 PM sun.rmi.transport.tcp.TCPEndpoint <clinit>
FINE: JConsole.addHost: localHostKnown = true, localHost = 10.206.6.59
Jan 5, 2012 2:30:43 PM sun.rmi.server.UnicastRef newCall
FINE: JConsole.addHost: get connection
Jan 5, 2012 2:30:43 PM sun.rmi.transport.tcp.TCPTransport <init>
FINE: JConsole.addHost: Version = 2, ep = [10.206.6.59:0]
Jan 5, 2012 2:30:43 PM sun.rmi.transport.tcp.TCPEndpoint getLocalEndpoint
FINE: JConsole.addHost: created local endpoint for socket factory null on port 0
Jan 5, 2012 2:30:43 PM sun.rmi.transport.tcp.TCPChannel createConnection
FINE: JConsole.addHost: create connection
Jan 5, 2012 2:30:43 PM sun.rmi.transport.tcp.TCPEndpoint newSocket
FINER: JConsole.addHost: opening socket to [10.40.243.12:12700]
Jan 5, 2012 2:30:43 PM sun.rmi.transport.proxy.RMIMasterSocketFactory createSocket
FINE: JConsole.addHost: host: 10.40.243.12, port: 12700
Jan 5, 2012 2:30:43 PM sun.rmi.transport.tcp.TCPChannel createConnection
FINER: JConsole.addHost: server suggested 10.206.6.59:12306
Jan 5, 2012 2:30:43 PM sun.rmi.transport.tcp.TCPChannel createConnection
FINER: JConsole.addHost: using 10.206.6.59:0
Jan 5, 2012 2:30:43 PM sun.rmi.server.UnicastRef newCall
FINER: JConsole.addHost: create call context
Jan 5, 2012 2:30:43 PM sun.rmi.server.UnicastRef logClientCall
FINER: JConsole.addHost: outbound call: [endpoint:[10.40.243.12:12700](remote),objID:[0:0:0, 0]] : sun.rmi.registry.RegistryImpl_Stub[0:0:0, 0]: java.rmi.Remote lookup(java.lang.String)
Jan 5, 2012 2:30:43 PM sun.rmi.transport.StreamRemoteCall <init>
FINER: JConsole.addHost: write remote call header...
Jan 5, 2012 2:30:43 PM sun.rmi.transport.StreamRemoteCall getOutputStream
FINER: JConsole.addHost: getting output stream
Jan 5, 2012 2:30:43 PM sun.rmi.server.UnicastRef invoke
FINER: JConsole.addHost: execute call
Jan 5, 2012 2:30:43 PM sun.rmi.transport.StreamRemoteCall getInputStream
FINER: JConsole.addHost: getting input stream
Jan 5, 2012 2:30:43 PM sun.rmi.server.LoaderHandler loadClass
FINE: JConsole.addHost: name = "javax.management.remote.rmi.RMIServerImpl_Stub", codebase = "", defaultLoader = sun.misc.Launcher$AppClassLoader@a39137
Jan 5, 2012 2:30:43 PM sun.rmi.server.LoaderHandler loadClass
FINER: JConsole.addHost: class "javax.management.remote.rmi.RMIServerImpl_Stub" found via defaultLoader, defined by null
Jan 5, 2012 2:30:43 PM sun.rmi.server.LoaderHandler loadClass
FINE: JConsole.addHost: name = "java.rmi.server.RemoteStub", codebase = "", defaultLoader = sun.misc.Launcher$AppClassLoader@a39137
Jan 5, 2012 2:30:43 PM sun.rmi.server.LoaderHandler loadClass
FINER: JConsole.addHost: class "java.rmi.server.RemoteStub" found via defaultLoader, defined by null
Jan 5, 2012 2:30:43 PM sun.rmi.server.LoaderHandler loadClass
FINE: JConsole.addHost: name = "java.rmi.server.RemoteObject", codebase = "", defaultLoader = sun.misc.Launcher$AppClassLoader@a39137
Jan 5, 2012 2:30:43 PM sun.rmi.server.LoaderHandler loadClass
FINER: JConsole.addHost: class "java.rmi.server.RemoteObject" found via defaultLoader, defined by null
Jan 5, 2012 2:30:43 PM sun.rmi.server.UnicastRef done
FINE: JConsole.addHost: free connection (reuse = true)
Jan 5, 2012 2:30:43 PM sun.rmi.transport.tcp.TCPChannel free
FINE: JConsole.addHost: reuse connection
Jan 5, 2012 2:30:43 PM sun.rmi.transport.tcp.TCPChannel free
FINE: JConsole.addHost: create reaper
Jan 5, 2012 2:30:43 PM sun.rmi.server.UnicastRef newCall
FINE: JConsole.addHost: get connection
Jan 5, 2012 2:30:43 PM sun.rmi.transport.tcp.TCPChannel createConnection
FINE: JConsole.addHost: create connection
Jan 5, 2012 2:30:43 PM sun.rmi.transport.tcp.TCPEndpoint newSocket
FINER: JConsole.addHost: opening socket to [tdiap12:41096]
Jan 5, 2012 2:30:43 PM sun.rmi.transport.proxy.RMIMasterSocketFactory createSocket
FINE: JConsole.addHost: host: tdiap12, port: 41096

第一次连接成功是因为在远程服务器上,我可以看到已经建立的连接。
wse2tst@tdiap12:~> netstat -a | grep 12700
tcp        0      0 *:12700                     *:*                         LISTEN      
tcp        0      0 tdiap12.vgcar.net:12700     per-00c0016253a2.vgca:12252 ESTABLISHED 

数据包跟踪指示连接成功。

第二个连接到端口41096超时,jconsole应用程序报告“连接失败”,并终止了第一个连接。为什么会尝试第二个连接?有没有办法指定第二个连接的端口?目标服务器受到严格控制,并且其他端口被防火墙规则阻止。在多次连接尝试中,第二个端口将更改为不同的随机值。

感谢任何帮助, Steve


你确定你的机器上没有防火墙阻止12700端口吗?我怀疑是因为某些阻塞,JMX正在尝试使用备用端口。请尝试禁用防火墙。 - kosa
当我尝试从本地机器连接时,远程机器显示以下内容:wse2tst@tdiap12:~> netstat -a | grep 12700 tcp 0 0 *:12700 *:* LISTEN tcp 0 0 tdiap12.vgcar.net:12700 per-00c0016253a2.vgca:12252 ESTABLISHED 我假设连接已经建立,并且没有被本地防火墙规则阻止。数据包跟踪也表明连接成功。 - Steven
我在文档中没有看到过这个。那会做什么呢?前两个 -Dcom.sun.management.jmxremote 值关闭加密和安全性。第三个定义了传入 JMX 连接的侦听端口。我认为仅设置 -Dcom.sun.management.jmxremote 不会产生任何影响。 - Steven
那我很抱歉!作为最后一次尝试,我会尝试从另一台远程机器上执行相同的操作(如果有的话)。我强烈怀疑你正在尝试连接的远程机器出了问题。 - kosa
@Steven,使用service:jmx:rmi:///jndi/rmi://XXXXXX:8091/jmxrmi无法连接到XXXXXXXX:8091。我遇到了这个错误,请问我做错了什么? - Jet
显示剩余3条评论
4个回答

9

除了手动编写代理的解决方案之外,更好的解决方案是使用新参数,该参数似乎在Java 7中引入:

-Dcom.sun.management.jmxremote.rmi.port=7091

因此,可以组合使用-使用相同的端口:

-Dcom.sun.management.jmxremote.port=7091 -Dcom.sun.management.jmxremote.rmi.port=7091

解决方案在此处找到: http://hirt.se/blog/?p=289


7

开箱即用的JMX实现使用两个端口——一个用于注册表(您指定的那个),另一个用于实际连接,其选择是随机的!这是一个相当大的设计缺陷,因为第二个端口的随机选择使得配置防火墙非常困难。

但是有解决办法——您可以自己 手动 解决,或者如果您使用Tomcat,可以让它 代为处理


事实证明,另一位开发人员已经编写了一个自定义代理来解决防火墙阻止第二个随机端口的问题。我决定找出问题的根源,而不是在需要监视的每个地方都安装自定义代理。(我必须监视大量应用服务器。)我非常沮丧,因为我从未找到确认第二个端口要求的文档,但您至少确认了我的观察结果,这对我来说已经足够了。感谢您的回答。 - Steven

2

请确保您使用以下命令运行应用程序:

java -Dcom.sun.management.jmxremote.port=9595 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -jar <your jar file name>

然后以管理员权限打开jconsole;您可能可以无问题地连接。

如果您想运行多个jar文件,请确保使用不同的端口;否则它将会报错,说已经被JVM绑定了。


请不要在多个问题中发布重复的答案。 - user229044

0

您可以使用参数-"Dcom.sun.management.jmxremote.rmi.port"设置第二个端口,其中端口号可以与第一个相同。即使设置了这个参数,它仍然会提示不安全的连接...请允许不安全的连接,否则在日志中将找到错误“无法连接:java.lang.SecurityException: Expecting a sun.rmi.server.UnicastRef2 remote reference in stub!”

谢谢


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