Como ativar o JMX em uma JVM para acessar com o jconsole?
Como ativar o JMX em uma JVM para acessar com o jconsole?
Respostas:
A documentação relevante pode ser encontrada aqui:
http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html
Inicie seu programa com os seguintes parâmetros:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9010
-Dcom.sun.management.jmxremote.rmi.port=9010
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Por exemplo, assim:
java -Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=9010 \
-Dcom.sun.management.jmxremote.local.only=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-jar Notepad.jar
-Dcom.sun.management.jmxremote.local.only=false
não é necessariamente necessário, mas sem ele, não funciona no Ubuntu. O erro seria algo como isto:
01 Oct 2008 2:16:22 PM sun.rmi.transport. customer .TCPTransport$AcceptLoop executeAcceptLoop
WARNING: RMI TCP Accept-0: accept loop for ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=37278] throws
java.io.IOException: The server sockets created using the LocalRMIServerSocketFactory only accept connections from clients running on the host where the RMI remote objects have been exported.
at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:89)
at sun.rmi.transport. customer .TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:387)
at sun.rmi.transport. customer .TCPTransport$AcceptLoop.run(TCPTransport.java:359)
at java.lang.Thread.run(Thread.java:636)
consulte http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6754672
Também tenha cuidado com o-Dcom.sun.management.jmxremote.authenticate=false
que torna o acesso disponível para qualquer pessoa, mas se você o usar apenas para rastrear a JVM em sua máquina local, isso não importa.
Atualização :
Em alguns casos, não consegui acessar o servidor. Isso foi corrigido se eu definir esse parâmetro também:-Djava.rmi.server.hostname=127.0.0.1
com.sun.management.jmxremote
tenha o valor padrão como true
. (Obrigado, Sun!) Para ser super claro, especialmente para aqueles menos familiarizados com os nobs JMX, eu uso: com.sun.management.jmxremote=true
Ref: docs.oracle.com/javase/8/docs/technotes/guides/management/…
Dcom.sun.management.jmxremote.rmi.port=9011
e abrir no firewall - ainda não consigo conectar com o firewall ativo. Alguma ideia? Perdi alguma coisa?
A execução em um contêiner do Docker introduziu uma série de problemas adicionais para conexão, por isso espero que isso ajude alguém. Acabei precisando adicionar as seguintes opções que explicarei abaixo:
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=${DOCKER_HOST_IP}
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.rmi.port=9998
DOCKER_HOST_IP
Ao contrário do jconsole localmente, você deve anunciar um IP diferente do que provavelmente verá no contêiner. Você precisará substituir ${DOCKER_HOST_IP}
pelo IP (nome DNS) externamente resolvível do seu host do Docker.
Portas remotas e RMI JMX
Parece que o JMX também requer acesso a uma interface de gerenciamento remoto ( jstat ) que usa uma porta diferente para transferir alguns dados ao arbitrar a conexão. Não vi nenhum lugar imediatamente óbvio jconsole
para definir esse valor. No artigo vinculado, o processo foi:
jconsole
com o log ativadojconsole
tentou usariptables
/ firewall
rules conforme necessário para permitir que a porta se conecteEnquanto isso funciona, certamente não é uma solução automatizável. Optei por uma atualização do jconsole para o VisualVM, pois permite especificar explicitamente a porta na qual jstatd
está sendo executada. No VisualVM, adicione um novo host remoto e atualize-o com valores que se correlacionam com os especificados acima:
Em seguida, clique com o botão direito do mouse na nova conexão de host remoto e Add JMX Connection...
Não se esqueça de marcar a caixa de seleção Do not require SSL connection
. Felizmente, isso deve permitir que você se conecte.
-Djava.rmi.server.hostname=localhost
-Dcom.sun.management.jmxremote.rmi.port=[...]
é também a chave no caso de tunelamento JMX / RMI através do SSH. Sem eles, os objetos remotos são acessados usando o IP público / principal / ... do servidor usando alguma porta aleatória, que não pode ser encaminhada facilmente.
-Djava.rmi.server.hostname=0.0.0.0
DOCKER_HOST_IP
em qualquer lugar - Eu apenas usei localhost
e transmitiu as portas ao executar a imagem janela de encaixe: -p 9998:9998, -p 9999:9999
etc.
Observe que o Java 6 na versão mais recente permite que o jconsole se conecte a um processo em execução, mesmo depois de ter sido iniciado sem os encantamentos do JMX.
Se isso estiver disponível, considere também o jvisualvm, pois fornece uma grande quantidade de informações sobre os processos em execução, incluindo um criador de perfil.
Estou usando o WAS ND 7.0
Minha JVM precisa que todos os seguintes argumentos sejam monitorados no JConsole
-Djavax.management.builder.initial=
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8855
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
No Linux, usei os seguintes parâmetros:
-Djavax.management.builder.initial=
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9010
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
e também editei /etc/hosts
para que o nome do host resolva para o endereço do host (192.168.0.x) em vez do endereço de loopback (127.0.0.1)
Execute seu aplicativo java com os seguintes parâmetros de linha de comando:
-Dcom.sun.management.jmxremote.port=8855
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
É importante usar o parâmetro -Dcom.sun.management.jmxremote.ssl = false se você não desejar configurar certificados digitais no host jmx.
Se você iniciou seu aplicativo em uma máquina com o endereço IP 192.168.0.1 , abra o jconsole , coloque 192.168.0.1:8855 no campo Processo Remoto e clique em Conectar .
-Dcom.sun.management.jmxremote.ssl=false
? Deveria jconsole
mostrar um erro ou apenas falharia discretamente na conexão?
junto com os parâmetros de linha de comando abaixo,
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Às vezes, nos servidores linux, a conexão imx não é bem-sucedida. isso ocorre porque, no host linux na nuvem, em / etc / hosts, para que o nome do host seja resolvido no endereço do host.
a melhor maneira de corrigi-lo é fazer o ping do servidor linux específico de outra máquina na rede e usar esse endereço IP do host no
-Djava.rmi.server.hostname=IP address that obtained when you ping that linux server.
Mas nunca confie no endereço ip que você obtém do servidor linux usando o ifconfig.me. o ip que você chegar lá é mascarado e está presente no arquivo host.
Primeiro, você precisa verificar se o seu processo java já está em execução com os parâmetros JMX. Faça isso:
ps -ef | grep java
Verifique seu processo java que você precisa monitorar. Se você puder ver o parâmetro jmx rmi Djmx.rmi.registry.port = xxxx , use a porta mencionada aqui em seu java visualvm para conectá-lo remotamente sob conexão jmx.
Se não estiver executando através da porta jmx rmi, será necessário executar o processo java com os parâmetros abaixo mencionados:
-Djmx.rmi.registry.port=1234 -Djmx.rmi.port=1235 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
Nota: os números de porta são baseados em sua escolha.
Agora você pode usar essa porta para a conexão jmx. Aqui é porto 1234
.
sudo lsof -i:1234
não está mostrando nada para mim
Etapa 1: execute o aplicativo usando os seguintes parâmetros.
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Os argumentos acima vinculam o aplicativo à porta 9999.
Etapa 2: Inicie o jconsole executando o comando jconsole no prompt de comando ou no terminal.
Selecione 'Processo remoto:' e digite o URL como {Endereço_IP}: 9999 e clique no botão Conectar para conectar-se ao aplicativo remoto.
Você pode consultar este link para obter a aplicação completa.
Eu tive esse problema exato e criei um projeto no GitHub para testar e descobrir as configurações corretas .
Ele contém um trabalho Dockerfile
com scripts de suporte e um simples docker-compose.yml
para testes rápidos.