Como corrijo um erro JMX 'Falha ao recuperar o stub do RMIServer'?

4

Acabei de concluir uma migração do Windows Server 2008 R2 para o Ubuntu 10.04. Eu gerencio um aplicativo java (Java 6, Tomcat) que está tendo alguns problemas de desempenho. Eu gostaria de usar o JMX para tentar solucionar problemas, mas parece que não consigo conectar o jvisualvm.

Se eu fizer um ps -ef | grep "java", vejo os seguintes parâmetros.

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

O Netstat mostra que a porta 8084 está escutando em 0.0.0.0. Na minha configuração, o JMX está configurado para vincular-se ao FQDN do servidor (usamos um servidor DNS privado). Meu firewall (IPTABLES / UFW) está configurado para permitir todo o tráfego de saída e para permitir tráfego de entrada na porta 8084.

O próprio servidor é virtual com dois NICs, um público e um privado. O gateway da NIC pública é desativado para que as conexões só possam entrar no lado privado.

Quando tento conectar o jvisualvm ao meu servidor de aplicativos usando o JMX, recebo o seguinte erro no jvisualvm.

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

Se eu olhar no log jvisualvm, vejo o seguinte rastreio.

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)

Alguém tem alguma ideia?

    
por GregB 06.09.2011 / 20:50

3 respostas

3

O problema é que, mesmo que o JMX esteja configurado para escutar na porta 8084, após a conexão inicial ser feita, o host JMX selecionará dinamicamente uma porta diferente para o restante da "conversação". Meu firewall permitia o tráfego através do 8084, mas estava bloqueando o tráfego subseqüente.

Existem duas opções.

  1. Permitir tráfego de entrada em todas as portas efêmeras (yikes!).
  2. Desenvolva um wrapper JMX que use uma única porta para comunicação.
por 07.02.2012 / 02:09
6

Você pode especificar a mesma porta para ambos Conversa de JMX e RMI:

-Dcom.sun.management.jmxremote.port=8084 
-Dcom.sun.management.jmxremote.rmi.port=8084 
    
por 25.11.2015 / 00:35
1

Eu lutei com esse mesmo problema ao tentar conectar-me às nossas novas VMs do Tomcat8 em vez do JMX (usando o VisualVM). Nossa equipe de Linux teve que abrir um ticket com a Redhat para nos ajudar a solucionar problemas. Mas eu tropecei neste artigo antes que eles pudessem resolver nosso problema.

A solução mencionada acima foi adicionar

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

e X devem corresponder ao que sua configuração é para

-Dcom.sun.management.jmxremote.port 

Lista completa de argumentos:

-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

Espero que isso ajude alguém a ter o mesmo problema. Boa sorte!

    
por 08.09.2017 / 21:22

Tags