Как исправить ошибку JMX "Не удалось получить заглушку RMIServer"?

Я только что завершил миграцию с 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 настроен для привязки к полному доменному имени сервера (мы используем частный DNS-сервер). Мой брандмауэр (IPTABLES/UFW) настроен так, чтобы разрешить весь исходящий трафик и разрешить входящий трафик через порт 8084.

Сам сервер является виртуальным с двумя сетевыми картами, публичной и частной. Шлюз общедоступной сетевой карты отключен, поэтому соединения могут входить только на частной стороне.

Когда я пытаюсь подключить jvisualvm к своему серверу приложений с помощью JMX, я получаю следующую ошибку в 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)

У кого-нибудь есть какие-либо идеи?

3 ответа

Решение

Проблема заключается в том, что даже если JMX настроен на прослушивание порта 8084, после установления первоначального соединения узел JMX будет динамически выбирать другой порт для оставшейся части "разговора". Мой брандмауэр пропускал трафик через 8084, но блокировал последующий трафик.

Есть два варианта.

  1. Разрешить входящий трафик на все временные порты (да!).
  2. Разработайте оболочку JMX, которая использует один порт для связи.

Вы можете указать один и тот же порт для диалога JMX и RMI:

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

Я боролся с этой же проблемой, пытаясь подключиться к нашим новым виртуальным машинам Tomcat8 через JMX (используя VisualVM). Наша команда 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

Надеюсь, что это помогает кому-то еще с той же проблемой. Удачи!

В поисках решения идентичной проблемы (после решения многих других, готовых рвать за волосы) я нашел эту ветку и могу поделиться, что решение, которое сработало для меня, было /questions/125317/kak-ispravit-oshibku-jmx-ne-udalos-poluchit-zaglushku-rmiserver/125332#125332 от @MaxRelax - Я бы поддержал его ответ, но у меня недостаточно репутации.

О, еще одна вещь: поскольку -Dcom.sun.management.jmxremote.ssl=falseОбязательно установите флажок "Не требовать SSL-соединение" в диалоговом окне Java Visual VM для добавления JMX-соединения.

У меня такая же проблема на 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
Другие вопросы по тегам