Как получить удаленный доступ к Spring-boot JMX
Я знаю, что весна автоматически выставляет бобы JMX. Я смог получить доступ к нему локально, используя VisualVM.
Однако на prod как я могу подключиться удаленно к приложению, используя его JMX beans? Есть ли порт по умолчанию или я должен определить что-нибудь дополнительно?
Спасибо,
луч.
3 ответов:
По умолчанию JMX автоматически доступен локально, поэтому запуск
jconsoleлокально будет обнаруживать все ваши локальные приложения java без доступа к порту.Чтобы получить доступ к приложению через JMX удаленно, необходимо указать порт реестра RMI. Дело в том, что при подключении JMX инициализируется на этом порту и тогда устанавливает соединение для передачи данных обратно наслучайный высокий порт , что является огромной проблемой, если у вас есть брандмауэр в середине. ("Эй сисадмины, просто откройте все, ладно?").
Чтобы заставить JMX снова подключиться к тому же порту, который вы установили, у вас есть несколько вариантов:
Вариант 1: Командная строка
-Dcom.sun.management.jmxremote.port=$JMX_REGISTRY_PORT -Dcom.sun.management.jmxremote.rmi.port=$RMI_SERVER_PORTЕсли вы используете Spring Boot, вы можете поместить это в свой файл
(appname).conf, который находится рядом с вашим развертыванием(appname).jar.Вариант 2: конфигурация Tomcat/Tomee
Настройте JmxRemoteLifecycleListener :
Maven Jar:
<dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-catalina-jmx-remote</artifactId> <version>8.5.9</version> <type>jar</type> </dependency>Настройте свой сервер.xml:
<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="10001" rmiServerPortPlatform="10002" />Вариант 3: Настройка программно
@Configuration public class ConfigureRMI { @Value("${jmx.rmi.host:localhost}") private String rmiHost; @Value("${jmx.rmi.port:1099}") private Integer rmiPort; @Bean public RmiRegistryFactoryBean rmiRegistry() { final RmiRegistryFactoryBean rmiRegistryFactoryBean = new RmiRegistryFactoryBean(); rmiRegistryFactoryBean.setPort(rmiPort); rmiRegistryFactoryBean.setAlwaysCreate(true); return rmiRegistryFactoryBean; } @Bean @DependsOn("rmiRegistry") public ConnectorServerFactoryBean connectorServerFactoryBean() throws Exception { final ConnectorServerFactoryBean connectorServerFactoryBean = new ConnectorServerFactoryBean(); connectorServerFactoryBean.setObjectName("connector:name=rmi"); connectorServerFactoryBean.setServiceUrl(String.format("service:jmx:rmi://%s:%s/jndi/rmi://%s:%s/jmxrmi", rmiHost, rmiPort, rmiHost, rmiPort)); return connectorServerFactoryBean; } }Хитрость, как вы увидите, заключается в
serviceUrl, в котором вы указываете как JMX:RMI host/port, так и jndi:RMI host/port. Если вы укажете оба, вы не получите случайную высокую "проблему".
Добавьте следующие свойства JVM в "$JAVA_OPTS " (в вашем приложении):
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=<PORT_NUMBER> -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=<HOST'S_IP>В JCONSOLE / Visual VM для подключения используйте следующее:
service:jmx:rmi:///jndi/rmi://<HOST'S_IP>:<PORT_NUMBER>/jmxrmiОн не обеспечивает безопасность, но поможет вам подключиться к удаленному серверу.
Протестированный подход на Java 1.8.0_71 и Spring Boot (1.3.3.ОСВОБОЖДАТЬ). Добавить ниже параметры аргументы JVM для мониторинга виртуальной машины.
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=12348 -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.rmi.port=12349 -Dcom.sun.management.jmxremote.password.file=/somewhere/jmxremote.password -Dcom.sun.management.jmxremote.access.file=/somewhere/jmx/jmxremote.access
com.sun.management.jmxremote.portиспользуется для определения фиксированного порта реестра RMI, аcom.sun.management.jmxremote.rmi.portиспользуется для указания JVM использовать фиксированный порт RMI, но не использовать случайный.Установив это, я могу подключить JVM-клиент с удаленного хоста к контролируемому JVM через брандмауэр, просто открыв порт 12348 и 12349.
Я протестировал с помощью
java -jar cmdline-jmxclient-0.10.3.jar user:pwd hostip:12348на удаленной машине, который генерирует ниже выходной сигнал (сокращенный только для демонстрации).java.lang:type=Runtime java.lang:name=PS Scavenge,type=GarbageCollector Tomcat:J2EEApplication=none,J2EEServer=none,WebModule=//localhost/,j2eeType=Filter,name=requestContextFilter java.nio:name=mapped,type=BufferPool Tomcat:host=localhost,type=Host java.lang:name=Compressed Class Space,type=MemoryPool .......Jar загружается изздесь .
Comments