Как активировать JMX на моей JVM для доступа через jconsole?
Как активировать JMX на JVM для доступа через jconsole?
12 ответов
Соответствующую документацию можно найти здесь:
http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html
Запустите вашу программу со следующими параметрами:
-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
Например, вот так:
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
не обязательно требуется, но без него он не работает в Ubuntu. Ошибка будет примерно такой:
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)
см. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6754672
Также будьте осторожны с-Dcom.sun.management.jmxremote.authenticate=false
что делает доступ доступным для всех, но если вы используете его только для отслеживания JVM на локальном компьютере, это не имеет значения.
Обновление:
В некоторых случаях я не смог добраться до сервера. Затем это было исправлено, если я также установил этот параметр: -Djava.rmi.server.hostname=127.0.0.1
Запуск в контейнере Docker привел к множеству дополнительных проблем при подключении, так что, надеюсь, это кому-нибудь поможет. В итоге мне нужно было добавить следующие параметры, которые я объясню ниже:
-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
В отличие от локального использования jconsole, вы должны рекламировать другой IP-адрес, который вы, вероятно, не увидите в контейнере. Вам нужно будет заменить ${DOCKER_HOST_IP}
с разрешаемым извне IP (DNS-именем) вашего хоста Docker.
Порты JMX Remote и RMI
Похоже, JMX также требуется доступ к интерфейсу удаленного управления ( jstat), который использует другой порт для передачи некоторых данных при арбитраже соединения. Я не видел нигде сразу очевидного в jconsole
установить это значение. В связанной статье процесс был:
- Попробуйте подключиться с
jconsole
с включенным ведением журнала - Потерпеть поражение
- Выяснить, какой порт
jconsole
пытался использовать - использование
iptables
/firewall
правила, необходимые для подключения этого порта
Хотя это работает, это, конечно, не автоматизируемое решение. Я выбрал обновление с jconsole до VisualVM, поскольку оно позволяет явно указать порт, на котором jstatd
бежит. В VisualVM добавьте новый удаленный хост и обновите его значениями, соответствующими указанным выше:
Затем щелкните правой кнопкой мыши новое подключение к удаленному хосту и Add JMX Connection...
Не забудьте установить флажок для Do not require SSL connection
, Надеюсь, это позволит вам подключиться.
Обратите внимание, что Java 6 в последней версии позволяет jconsole присоединяться к работающему процессу даже после того, как он был запущен без заклинаний JMX.
Если это доступно вам, также рассмотрите jvisualvm, поскольку он предоставляет обширную информацию о запущенных процессах, включая профилировщик.
Я использую WAS ND 7.0
Моей JVM необходимо отслеживать все следующие аргументы в 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
В Linux я использовал следующие параметры:
-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
а также я отредактировал /etc/hosts
так что имя хоста разрешается в адрес хоста (192.168.0.x), а не адрес обратной связи (127.0.0.1)
Для меня подходят следующие варианты:
-Dcom.sun.management.jmxremote=true
-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
-Djava.rmi.server.hostname={host name}
и не забудьте открыть порт 9010 на сервере
sudo ufw allow 9010/udp
sudo ufw allow 9010/tcp
sudo ufw reload
Наряду с нижеприведенными параметрами командной строки,
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Иногда на серверах Linux соединение IMX не удается. Это связано с тем, что в облачном хосте Linux, в /etc/hosts, чтобы имя хоста соответствовало адресу хоста.
лучший способ исправить это - пропинговать конкретный сервер linux с другого компьютера в сети и использовать этот IP-адрес хоста в
-Djava.rmi.server.hostname=IP address that obtained when you ping that linux server.
Но никогда не полагайтесь на ipaddress, полученный с сервера Linux с помощью ifconfig.me. IP-адрес, который вы получаете там, является маскированным, который присутствует в файле хоста.
Запустите ваше Java-приложение со следующими параметрами командной строки:
-Dcom.sun.management.jmxremote.port=8855
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Важно использовать параметр -Dcom.sun.management.jmxremote.ssl=false, если вы не хотите устанавливать цифровые сертификаты на хосте jmx.
Если вы запустили ваше приложение на компьютере с IP-адресом 192.168.0.1, откройте jconsole, поместите 192.168.0.1:8855 в поле Удаленный процесс и нажмите Подключиться.
ЗАПУСК ЛОКАЛЬНОГО ПРОЦЕССА JCONSOLE с использованием опции удаленного процесса
Для локального запуска это сработало для меня -
Я добавил это в свои аргументы vm -
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=6001
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=localhost
-Dcom.sun.management.jmxremote.rmi.port=6001
I opened JConsole via Intellij Terminal
It was showing me all PID's in grey in local
So I selected remote process and logged in using host - localhost:6001
Keep empty username & password
Then click connect
- Убедитесь, что на порту 6001 не запущен другой процесс. Вы также можете использовать другие порты.
Шаг 1: Запустите приложение, используя следующие параметры.
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Вышеуказанные аргументы связывают приложение с портом 9999.
Шаг 2: Запустите jconsole, выполнив команду jconsole в командной строке или терминале.
Выберите "Удаленный процесс:" и введите URL-адрес как {IP_Address}:9999 и нажмите кнопку "Подключиться", чтобы подключиться к удаленному приложению.
Вы можете перейти по этой ссылке для получения полной заявки.
Во-первых, вам нужно проверить, работает ли ваш Java-процесс с параметрами JMX. Сделай это:
ps -ef | grep java
Проверьте ваш Java-процесс, который нужно отслеживать. Если вы видите параметр jmx rmi Djmx.rmi.registry.port=xxxx, то используйте порт, упомянутый здесь, в вашем java visualvm, чтобы удаленно подключить его через соединение jmx.
Если он не работает через порт jmx rmi, вам нужно запустить процесс java с указанными ниже параметрами:
-Djmx.rmi.registry.port=1234 -Djmx.rmi.port=1235 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
Примечание: номера портов основаны на вашем выборе.
Теперь вы можете использовать этот порт для соединения jmx. Вот это порт 1234
,
У меня была именно эта проблема, и я создал проект GitHub для тестирования и определения правильных настроек.
Содержит рабочий Dockerfile
с поддержкой сценариев и простым docker-compose.yml
для быстрого тестирования.