habilitar java rmi jmx jconsole

java - habilitar - ¿Cómo hacer que JMX se una a una interfaz específica?



habilitar jmx (5)

Fernando ya proporcionó un enlace a mi publicación de blog :) ... no es trivial. Debe proporcionar su propio RMIServerSocketFactoryImpl que crea conectores en la dirección deseada.

Si las interfaces internas / externas son el problema y tiene acceso local a la configuración de un servidor de seguridad local, puede ser más fácil.

Actualmente estoy iniciando mi Java VM con las propiedades com.sun.management.jmxremote.* poder conectarme a ella a través de JConsole para la administración y la supervisión. Desafortunadamente, escucha en todas las interfaces (direcciones IP) en la máquina.

En nuestro entorno, a menudo hay casos en los que hay más de una Java VM ejecutándose en una máquina al mismo tiempo. Si bien es posible decirle a JMX que escuche en diferentes puertos TCP (usando com.sun.management.jmxremote.port ), sería bueno tener JMX en su lugar usar el puerto JMX estándar y simplemente enlazar a una dirección IP específica (en lugar de todo de ellos).

Esto facilitaría mucho más descubrir a qué máquina virtual nos estamos conectando a través de JConsole (ya que cada máquina virtual "posee" efectivamente su propia dirección IP). ¿Alguien ha descubierto cómo hacer que JMX escuche en una sola dirección IP o nombre de host?


La respuesta aceptada es bastante antigua. Hay algunas indicaciones de que Java ahora proporciona algunas opciones para habilitar esto. Por ejemplo, he visto:

-Djava.rmi.server.hostname=<YOUR_IP>

...tanto como...

-Dcom.sun.management.jmxremote.host=<YOUR_IP>

Sin embargo, al menos en mi sistema bajo jdk 1.7, estos no parecen tener ningún efecto: el conector JMX aún se une a *. Una respuesta actualizada (con versiones específicas aplicables) sería muy apreciada. Esto debería ser simple.


No lo he intentado pero esto puede ayudar.

La principal molestia aquí es que no hay una manera fácil de especificar la dirección IP del host para que JMX se vincule, siempre se vincularía a todas las interfaces. La propiedad ''java.rmi.server.hostname'' no funcionaba y no quería elegir puertos diferentes para todas las instancias diferentes en el mismo host.

Además, no quería crear mi propio RMIServerSocketFactory con todas las complejidades asociadas con él, buscaba un parche simple para el código existente.

Lo solucioné parcheando la fábrica de sockets JVM RMI por defecto que es responsable de crear este socket de servidor. Ahora es compatible con la nueva propiedad ''com.sun.management.jmxremote.host''.

Para que esto funcione, guarde el siguiente código Java en un archivo denominado sun / rmi / transport / proxy / RMIDirectSocketFactory.java.

Compile y cree jmx_patch.jar a partir de él y colóquelo en la carpeta lib / tomcat.

Luego debe agregar la siguiente línea a bin / setenv.sh:

CLASSPATH = $ CLASSPATH: $ CATALINA_HOME / lib / mx_patch.jar

agregue esta opción en el arranque de la instancia de tomcat

-Dcom.sun.management.jmxremote.host = 192.168.100.100 "

Esto vinculará el servicio JMX solo a la dirección 192.168.100.100. Los otros 2 puertos de escucha RMI aleatorios aún se vincularán a todas las interfaces, pero eso está bien ya que siempre escogen un puerto libre de todos modos.

Ahora puede ejecutar múltiples instancias de tomcat en un solo host con todos los puertos predeterminados intactos (por ejemplo, 8080 para JMX para todos ellos).

package sun.rmi.transport.proxy; import java.io.IOException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.rmi.server.RMISocketFactory; public class RMIDirectSocketFactory extends RMISocketFactory { public Socket createSocket(String host, int port) throws IOException { return new Socket(host, port); } public ServerSocket createServerSocket(int port) throws IOException { String jmx_host = System.getProperty("com.sun.management.jmxremote.host"); String jmx_port = System.getProperty("com.sun.management.jmxremote.port"); // Allow JMX to bind to specific address if (jmx_host != null && jmx_port != null && port != 0 && integer.toString(port).equals(jmx_port)) { InetAddress[] inetAddresses = InetAddress.getAllByName(jmx_host); if (inetAddresses.length > 0) { return new ServerSocket(port, 50, inetAddresses[0]); } } return new ServerSocket(port); }

}



Yo solo intenté

-Dcom.sun.management.jmxremote.host =

con openjdk 1.8, y funciona bien. Se une a esa addess (de acuerdo con netstat) y todo se ve bien (y funciona).