远程 JMX 调用上的 NoRouteToHostException / NoSuchHostException

Posted

技术标签:

【中文标题】远程 JMX 调用上的 NoRouteToHostException / NoSuchHostException【英文标题】:NoRouteToHostException / NoSuchHostException on remote JMX call 【发布时间】:2012-06-05 15:31:41 【问题描述】:

我在 Centos 5.6 服务器上对 JBoss 6 进行远程 JMX 调用时遇到问题。我以前在 Debian 服务器上运行相同的应用程序时能够做到这一点。

./twiddle.sh --server=service:jmx:rmi:///jndi/rmi://SERVER:1090/jmxconnector invoke foo:service=bar baz

Caused by: java.net.NoRouteToHostException: No route to host
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
    at java.net.Socket.connect(Socket.java:529)
    at java.net.Socket.connect(Socket.java:478)
    at java.net.Socket.<init>(Socket.java:375)
    at java.net.Socket.<init>(Socket.java:189)
    at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22)
    at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:128)
    at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:595)

如果我在 SERVER 上本地运行,同样的调用会成功。我已经用 iptables 打开了端口 1090,我可以通过 telnet 连接到 SERVER:1090。 hostname -i 返回正确的 IP 地址。

我也试过用-Djava.rmi.server.hostname=localhost 启动JBoss。如果我这样做,那么我会得到一个不同的异常:

Caused by: java.rmi.NoSuchObjectException: no such object in table
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142)
    at javax.management.remote.rmi.RMIServerImpl_Stub.newClient(Unknown Source)
    at javax.management.remote.rmi.RMIConnector.getConnection(RMIConnector.java:2327)
    at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:279)
    at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:248)
    at org.jboss.console.twiddle.Twiddle.createMBeanServerConnection(Twiddle.java:322)
    at org.jboss.console.twiddle.Twiddle.connect(Twiddle.java:331)
    at org.jboss.console.twiddle.Twiddle.access$400(Twiddle.java:60)
    at org.jboss.console.twiddle.Twiddle$1.getServer(Twiddle.java:217)

【问题讨论】:

如果使用服务器的 IP 地址进行 JMX 调用会发生什么? @SamGoldberg 不幸的是,同样的事情 【参考方案1】:

事实证明,除了端口 1090,JMX/RMI 还使用动态分配的端口,该端口被防火墙阻止。因此,如果合适,请完全禁用防火墙,否则这似乎是一种替代方案(我还没有尝试过):

http://olegz.wordpress.com/2009/03/23/jmx-connectivity-through-the-firewall/

【讨论】:

另一种方法是设置一种 ***,通过隧道将整个端口范围路由到特定 IP 地址。我的一个客户已经在 C 中实现了他们自己的 JVM 代理,以便能够通过 SSH 传输 JMX 协议……这真是一个常见的问题。【参考方案2】:

我做的是这样的:

更新文件 activemq.xml 并指定 rmiServerPort。

<managementContext createConnector="true" connectorPort="SOME_PORT" rmiServerPort="SOME_OTHER" jmxDomainName="org.apache.activemq"/>

通过更新您的 iptables 条目来允许这两个端口,重新启动 activemq,它应该可以工作。

【讨论】:

以上是关于远程 JMX 调用上的 NoRouteToHostException / NoSuchHostException的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 JMX 连接到远程 Docker 容器

jmx/jstatd 通过 ssh 隧道访问远程机器

如何通过JMX远程监控Solr?

Hadoop jar配置使用JMX进行远程JVM监控

远程连接JMX出现问题

JConsole的设置及远程连接