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.