【问题标题】:Java jconsole jmx connection failureJava jconsole jmx 连接失败
【发布时间】:2012-01-04 22:24:05
【问题描述】:

我正在尝试将 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

loggin.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

第一次连接尝试成功,因为在远程服务器上,我可以看到 ESTABLISHED 连接。

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

感谢您的帮助, 史蒂夫

【问题讨论】:

  • 您确定您的机器上没有防火墙阻止 12700?我怀疑由于一些阻塞,jmx 正在尝试替代端口。尝试禁用防火墙。
  • 当我尝试从本地机器连接时,远程机器显示如下:wse2tst@tdiap12:~&gt; netstat -a | grep 12700 tcp 0 0 *:12700 *:* LISTEN tcp 0 0 tdiap12.vgcar.net:12700 per-00c0016253a2.vgca:12252 ESTABLISHED 我假设连接正在建立并且没有被本地防火墙规则阻止。数据包跟踪也表明连接成功。
  • 我猜你需要添加-Dcom.sun.management.jmxremote,同时调出你在这个问题之上指定的jvm,我们不需要吗?
  • 我在文档中没有看到。那会做什么?前两个 -Dcom.sun.management.jmxremote 值轮流加密和安全。第三个定义传入 JMX 连接的侦听端口。我认为单独设置 -Dcom.sun.management.jmxremote 不会有任何影响。
  • 试试看。它让你的 JVM 寻找远程连接。

标签: jmx jconsole


【解决方案1】:

比使用手动编码代理更好的新解决方案是使用似乎在 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

【讨论】:

    【解决方案2】:

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

    但是有一些方法可以解决它 - 你可以自己做 manually,或者如果你使用的是 Tomcat,你可以让它 handle it for you

    【讨论】:

    • 原来另一个开发人员已经编写了一个自定义代理来解决防火墙阻塞第二个随机端口的问题。我决心彻底解决问题,而不必在需要监控的任何地方安装自定义代理。 (我必须监控大量的应用程序服务器。)我非常沮丧,因为我从未找到确定第二个端口要求的文档,但你至少证实了我的观察,这对我来说已经足够了。感谢您的回答。
    【解决方案3】:

    确保您使用以下命令运行您的应用程序,

    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 绑定了

    【讨论】:

    • 请不要发布多个问题的重复答案。
    【解决方案4】:

    您可以使用参数-"Dcom.sun.management.jmxremote.rmi.port" 设置第二个端口,其中端口号可以与第一个端口号相同。即使在设置后,它也会提示不安全的连接......请允许不安全的连接,然后只有它才会允许您继续进行,否则在日志中您会发现错误无法连接:java.lang.SecurityException:期待sun.rmi .server.UnicastRef2 存根中的远程引用!

    谢谢

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-18
      • 1970-01-01
      相关资源
      最近更新 更多