actuator spring spring-boot jmx

spring boot actuator maven



Cómo acceder a Spring-boot JMX de forma remota (3)

Agregue las siguientes propiedades de JVM en "$ JAVA_OPTS" (en su aplicación):

-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>

En la Jconsole / Visual VM use lo siguiente para conectarse:

service:jmx:rmi:///jndi/rmi://<HOST''S_IP>:<PORT_NUMBER>/jmxrmi

No habilita la seguridad, pero le ayudará a conectarse al servidor remoto.

Sé que la primavera expone automáticamente los frijoles JMX. Pude acceder a él localmente mediante VisualVM.

Sin embargo, ¿cómo puedo conectarme de forma remota a la aplicación utilizando sus beans JMX? ¿Hay un puerto predeterminado o debo definir algo además?

Gracias, Ray.


Un enfoque probado en Java 1.8.0_71 y Spring Boot (1.3.3.RELEASE). Agregue los siguientes parámetros a los argumentos JVM para JVM supervisados.

-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

El com.sun.management.jmxremote.port se usa para definir el puerto de registro RMI fijo, y el com.sun.management.jmxremote.rmi.port se usa para indicar a JVM que use el puerto RMI fijo, pero NO use uno aleatorio.

Al configurar esto, puedo conectar el cliente JVM desde el host remoto a la JVM monitoreada a través de un firewall que abre los puertos 12348 y 12349.

java -jar cmdline-jmxclient-0.10.3.jar user:pwd hostip:12348 utilizando java -jar cmdline-jmxclient-0.10.3.jar user:pwd hostip:12348 en una máquina remota, que genera una salida inferior (acortada solo para demostración).

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 .......

El tarro se descarga desde Here .


De forma predeterminada, se puede acceder a JMX de forma automática a nivel local, por lo que la ejecución de jconsole localmente detectaría todas las aplicaciones java locales sin exposición a puertos.

Para acceder a una aplicación a través de JMX de forma remota , debe especificar un puerto de registro RMI. Lo que hay que saber es que al conectarse, JMX se inicializa en ese puerto y luego establece una conexión de datos en un puerto alto aleatorio , lo cual es un gran problema si tiene un firewall en el medio. ("Hey sysadmins, solo abre todo, mkay?").

Para forzar a JMX a que vuelva a conectarse en el mismo puerto que ha establecido, tiene un par de opciones:

Opción 1: línea de comando

-Dcom.sun.management.jmxremote.port=$JMX_REGISTRY_PORT -Dcom.sun.management.jmxremote.rmi.port=$RMI_SERVER_PORT

Si está utilizando Spring Boot, puede poner esto en su archivo (appname).conf que se encuentra junto a su implementación (appname).jar .

Opción 2: configuración Tomcat / Tomee

Configure un JmxRemoteLifecycleListener :

Maven Jar:

<dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-catalina-jmx-remote</artifactId> <version>8.5.9</version> <type>jar</type> </dependency>

Configure su server.xml:

<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="10001" rmiServerPortPlatform="10002" />

Opción 3: configurar programáticamente

@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; } }

El truco, verás, es el serviceUrl en el que especificas tanto el host / puerto jmx: rmi como el host / puerto jndi: rmi. Si especifica ambos, no obtendrá el "problema" alto aleatorio.