2008-12-01 12 views
17

Actualmente estoy iniciando mi Java VM con las propiedades com.sun.management.jmxremote.*, de modo que me pueda conectar a través de JConsole para la administración y el monitoreo. Desafortunadamente, escucha en todas las interfaces (direcciones IP) en la máquina.¿Cómo hacer que JMX se una a una interfaz específica?

En nuestro entorno, a menudo hay casos en los que hay más de una máquina virtual de Java 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 que JMX usara el puerto JMX estándar y simplemente se una a una dirección IP específica (en lugar de a todas).

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 efectivamente "posee" su propia dirección IP). ¿Alguien ha descubierto cómo hacer que JMX escuche en una sola dirección IP o nombre de host?

Respuesta

15

Si alguien más va a perder sus nervios con esto ... Después de 10 años, que finalmente arreglaron!

Desde Java 8u102 -Dcom.sun.management.jmxremote.host se une a la IP seleccionada

véase: https://bugs.openjdk.java.net/browse/JDK-6425769

8

Fernando ya proporcionó un enlace a my blog post :) ... 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, la configuración de un firewall local puede ser más fácil.

+0

Gracias - No pensé que sería simple o bonito. :) –

-3

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

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

... así como ...

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

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

+0

Ninguno de estos controles controla la dirección. 'java.rmi.server.hostname' no es nuevo, ha estado allí durante 17 años, y dudo que el otro sea nuevo tampoco. – EJP

+0

No dije que eran nuevos. Dije que los había visto y que no funcionaron. – sosiouxme

+0

Tenía la esperanza de que hubiera alguna manera de que realmente funcionara sin ser horrible. No he encontrado ninguno. – sosiouxme

0

No he intentado esto 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 el enlace de JMX, siempre se vinculará a todas las interfaces. La propiedad 'java.rmi.server.hostname' no funcionaba y no deseaba 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 he arreglado parcheando la fábrica de socket RMI JVM predeterminada 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 llamado sun/rmi/transport/proxy/RMIDirectSocketFactory.java.

Compila y crea jmx_patch.jar a partir de él y colócalo en la carpeta tomcat lib/ .

A continuación, deberá añadir la siguiente línea a bin/setenv.sh:

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

añadir esta opción en la instancia de Tomcat arranque

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

Esto entonces se unirá al servicio JMX única para hacer frente a 192.168.100.100. los otros 2 puertos de escucha RMI al azar todavía se unirán a todas las interfaces, pero eso está bien , ya que siempre que busque un puerto libre de todos modos.

ahora puede ejecutar varias instancias de Tomcat en un único host con todos los puertos predeterminados intacto (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); 
    } 

}

0

Sólo traté

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

+0

Es una respuesta duplicada. ¿Tal vez quería agregar un comentario a la respuesta original? – Richlv

Cuestiones relacionadas