Tomcat
如何修復“無法檢索 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 上的傳入流量。
伺服器本身是虛擬的,有兩個 NIC,一個公共的和一個私有的。公共 NIC 的網關被禁用,因此連接只能從私有端進入。
當我嘗試使用 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)
有沒有人有任何想法?
問題是,即使 JMX 被配置為偵聽埠 8084,在建立初始連接後,JMX 主機也會為其餘的“對話”動態選擇不同的埠。我的防火牆允許流量通過 8084,但阻止了後續流量。
有兩種選擇。
- 允許所有臨時埠上的入站流量(哎呀!)。
- 開發使用單個埠進行通信的 JMX 包裝器。
您可以為 JMX 和 RMI 對話指定相同的埠:
-Dcom.sun.management.jmxremote.port=8084 -Dcom.sun.management.jmxremote.rmi.port=8084