如何修复“无法检索 RMIServer 存根”JMX 错误?

如何修复“无法检索 RMIServer 存根”JMX 错误?

我刚刚完成了从 Windows Server 2008 R2 到 Ubuntu 10.04 的迁移。我管理的 Java 应用程序(Java 6、Tomcat)存在一些性能问题。我想使用 JMX 来尝试排除故障,但似乎无法让 jvisualvm 连接。

如果我执行 ps -ef | grep "java",我会看到以下参数。

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

Netstat 显示端口 8084 正在监听 0.0.0.0。在我的配置中,JMX 设置为绑定到服务器的 FQDN(我们使用私有 DNS 服务器)。我的防火墙(IPTABLES/UFW)设置为允许所有传出流量,并允许端口 8084 上的传入流量。

服务器本身是虚拟的,有两个网卡,一个是公网,一个是私网。公网网卡的网关被禁用,因此连接只能从私网一侧进入。

当我尝试使用 JMX 将 jvisualvm 连接到我的应用服务器时,jvisualvm 中出现以下错误。

Cannot connect to [FQDN OMITTED]:8084 using server:jmx:rmi:///jndi/rmi://[FQDN OMITTED]:8084/jmxrmi

如果我查看 jvisualvm 日志,我会看到以下跟踪。

NFO [com.sun.tools.visualvm.jmx.impl.JmxModelImpl]: connect(service:jmx:rmi:///jndi/rmi://[FQDN OMITTED]:8084/jmxrmi)
java.io.EOFException: SSL peer shut down incorrectly
                at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:333)
                at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:789)
Caused: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
                at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:808)
                at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1120)
                at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:623)
                at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
                at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
                at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
                at java.io.DataOutputStream.flush(DataOutputStream.java:106)
                at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:211)
Caused: java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is: 
                javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
                at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:286)
                at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:184)
                at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:322)
                at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
                at com.sun.jndi.rmi.registry.RegistryContext.lookup(RegistryContext.java:97)
Caused: javax.naming.CommunicationException [Root exception is java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is: 
                javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake]
                at com.sun.jndi.rmi.registry.RegistryContext.lookup(RegistryContext.java:101)
                at com.sun.jndi.toolkit.url.GenericURLContext.lookup(GenericURLContext.java:185)
                at javax.naming.InitialContext.lookup(InitialContext.java:392)
                at javax.management.remote.rmi.RMIConnector.findRMIServerJNDI(RMIConnector.java:1886)
                at javax.management.remote.rmi.RMIConnector.findRMIServer(RMIConnector.java:1856)
                at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:257)
Caused: java.io.IOException: Failed to retrieve RMIServer stub
                at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:338)
                at com.sun.tools.visualvm.jmx.impl.JmxModelImpl$ProxyClient.tryConnect(JmxModelImpl.java:451)
[catch] at com.sun.tools.visualvm.jmx.impl.JmxModelImpl$ProxyClient.connect(JmxModelImpl.java:395)
                at com.sun.tools.visualvm.jmx.impl.JmxModelImpl.connect(JmxModelImpl.java:216)
                at com.sun.tools.visualvm.jmx.impl.JmxModelImpl.<init>(JmxModelImpl.java:205)
                at com.sun.tools.visualvm.jmx.impl.JmxModelProvider.createModelFor(JmxModelProvider.java:61)
                at com.sun.tools.visualvm.jmx.impl.JmxModelProvider.createModelFor(JmxModelProvider.java:42)
                at com.sun.tools.visualvm.core.model.ModelFactory.getModel(ModelFactory.java:111)
                at com.sun.tools.visualvm.tools.jmx.JmxModelFactory.getJmxModelFor(JmxModelFactory.java:69)
                at com.sun.tools.visualvm.jmx.impl.JmxApplicationProvider.addJmxApplication(JmxApplicationProvider.java:267)
                at com.sun.tools.visualvm.jmx.impl.JmxApplicationProvider.createJmxApplication(JmxApplicationProvider.java:185)
                at com.sun.tools.visualvm.jmx.JmxApplicationsSupport.createJmxApplicationImpl(JmxApplicationsSupport.java:283)
                at com.sun.tools.visualvm.jmx.JmxApplicationsSupport.createJmxApplicationInteractive(JmxApplicationsSupport.java:261)
                at com.sun.tools.visualvm.jmx.impl.AddJMXConnectionAction$1.run(AddJMXConnectionAction.java:80)
                at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:577)
                at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:1030)

有人有什么想法吗?

答案1

您可以指定同一端口对于 JMX 和 RMI 对话:

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

答案2

问题是,即使 JMX 配置为侦听端口 8084,在建立初始连接后,JMX 主机也会动态地为其余的“对话”选择不同的端口。我的防火墙允许流量通过 8084,但阻止了后续流量。

有两个选择。

  1. 允许所有临时端口上的入站流量(哎呀!)。
  2. 开发使用单个端口进行通信的 JMX 包装器。

答案3

我在尝试通过 JMX(使用 VisualVM)连接到我们的新 Tomcat8 VM 时遇到了同样的问题。我们的 Linux 团队不得不向 Redhat 开具一张工单来帮助我们排除故障。但在他们解决我们的问题之前,我偶然发现了这篇文章。

如上所述的解决方案是添加

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

并且X应该匹配你的设置

-Dcom.sun.management.jmxremote.port 

完整的参数列表:

-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=8091
-Dcom.sun.management.jmxremote.rmi.port=8091
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false 
-Djava.rmi.server.hostname=MYHOST

希望这能帮助遇到同样问题的人。祝你好运!

答案4

我在 tomcat 9.0.9 上也遇到了同样的问题。path/to/tomcat/bin/setenv.sh以下配置对我有用:

CATALINA_OPTS="$CATALINA_OPTS 
-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=1099 
-Dcom.sun.management.jmxremote.rmi.port=1099 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false 
-Djava.rmi.server.hostname=192.168.1.20 
-Djmx.rmi.registry.port=1099 
-Djmx.rmi.port=1099 
" 

export CATALINA_OPTS

相关内容