Как получить удаленный доступ к Spring-boot JMX



Я знаю, что весна автоматически выставляет бобы JMX. Я смог получить доступ к нему локально, используя VisualVM.



Однако на prod как я могу подключиться удаленно к приложению, используя его JMX beans? Есть ли порт по умолчанию или я должен определить что-нибудь дополнительно?



Спасибо,
луч.

816   3  

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

    Ничего не найдено.