1. Обзор
В этом руководстве мы объясним, почему JMX открывает три порта при запуске. Кроме того, мы покажем, как запустить JMX в Java. После этого мы покажем, как ограничить количество открытых портов.
2. Определение JMX
Давайте сначала определим, что такое фреймворк JMX. Платформа Java Management Extensions (JMX) предоставляет настраиваемую, масштабируемую и надежную инфраструктуру для управления Java-приложениями. Кроме того, он определяет концепцию MBean для управления приложением в реальном времени. Фреймворк позволяет управлять приложением локально или удаленно.
3. Включите JMX в Java
Давайте теперь посмотрим, как включить JMX. Для Java версии 1.5 и более ранних существует системное свойство com.sun.management.jmxremote .
Приложение, запущенное с этим свойством, позволяет подключаться к JConsole как локально, так и удаленно. С другой стороны, приложение не видно из JConsole при запуске без свойства.
Однако, начиная с Java 6 и выше, параметр не нужен . Приложение автоматически становится доступным для управления после запуска. Кроме того, конфигурация по умолчанию назначает порт автоматически и предоставляет его только локально.
4. Порты JMX
В наших примерах мы будем использовать Java 6 или выше. Во-первых, давайте создадим класс с бесконечным циклом. Класс ничего не делает, но позволяет нам проверить, какие порты открыты:
public class JMXConfiguration {
public static void main(String[] args) {
while (true) {
// to ensure application does not terminate
}
}
}
Теперь мы скомпилируем класс и запустим его:
java com.foreach.jmx.JMXConfiguration
После этого мы можем проверить, какой pid назначен процессу, и проверить порты, открытые процессом :
netstat -ao | grep <pid>
В результате мы получим список портов, открытых нашим приложением:
Active Connections
Proto Local Address Foreign Address State PID
TCP 127.0.0.1:55846 wujek:55845 ESTABLISHED 2604
Кроме того, в случае перезагрузки порт изменится . Он назначается случайным образом. Эта функциональность доступна, начиная с Java 6, которая автоматически предоставляет приложение для Java Attach API. Другими словами, он автоматически предоставляет приложение для подключения JConsole через локальный процесс.
Давайте теперь включим удаленные подключения, предоставив параметры JVM:
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=1234
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Номер порта является обязательным параметром, который мы должны указать, чтобы предоставить JMX для удаленного подключения. Мы отключили аутентификацию и SSL только в целях тестирования.
Теперь команда netstat
возвращает:
Proto Local Address Foreign Address State PID
TCP 0.0.0.0:1234 wujek:0 LISTENING 11088
TCP 0.0.0.0:58738 wujek:0 LISTENING 11088
TCP 0.0.0.0:58739 wujek:0 LISTENING 11088
Как мы видим, приложение выставило три порта. RMI/JMX предоставляет два порта. Третий — случайный порт для локального подключения.
5. Ограничьте количество открытых портов
Прежде всего, мы можем отключить предоставление приложения для локального подключения из JConsole с помощью параметра -XX:+DisableAttachMechanism
:
java -XX:+DisableAttachMechanism com.foreach.jmx.JMXConfiguration
После этого приложение не предоставляет никаких портов JMX/RMI.
Кроме того, начиная с JDK 16, мы можем установить номер локального порта:
java
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.local.port=1235
com.foreach.jmx.JMXConfiguration
Давайте теперь изменим конфигурацию и поиграем с удаленными портами.
Существует дополнительная опция -Dcom.sun.management.jmxremote.rmi.port=1234
, которая позволяет нам установить для порта RMI то же значение, что и для порта JMX. Теперь полная команда:
java
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=1234
-Dcom.sun.management.jmxremote.rmi.port=1234
-Dcom.sun.management.jmxremote.local.port=1235
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
com.foreach.jmx.JMXConfiguration
После этого команда netstat
возвращает:
Proto Local Address Foreign Address State PID
TCP 0.0.0.0:1234 wujek:0 LISTENING 19504
TCP 0.0.0.0:1235 wujek:0 LISTENING 19504
Другими словами, приложение предоставляет только два порта: один для удаленного соединения JMX/RMI и один для локального соединения. Благодаря этому мы можем полностью контролировать открытые порты и избегать конфликтов с портами, открытыми другими процессами.
Однако, когда мы разрешаем удаленное подключение и отключаем механизм подключения:
java
-XX:+DisableAttachMechanism
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=1234
-Dcom.sun.management.jmxremote.rmi.port=1234
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
com.foreach.jmx.JMXConfiguration
Затем приложение по-прежнему предоставляет два порта:
Proto Local Address Foreign Address State PID
TCP 0.0.0.0:1234 wujek:0 LISTENING 9856
TCP 0.0.0.0:60565 wujek:0 LISTENING 9856
6. Заключение
В этой короткой статье мы объяснили, как запустить JMX в Java. Затем мы показали, какие порты открывает JMX при запуске. Наконец, мы представили, как ограничить количество портов, открываемых JMX.
Как всегда, исходный код примера доступен на GitHub .