Pregunta

Actualmente estoy iniciando mi Java VM con las propiedades com.sun.management.jmxremote.* para poder conectarme a él a través de JConsole para administración y monitoreo. 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 máquina virtual 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 uniera a un dirección IP específica (en lugar de todas).

Esto facilitaría mucho determinar a qué VM nos estamos conectando a través de JConsole (dado que cada VM 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?

¿Fue útil?

Solución

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

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

ver: https://bugs.openjdk.java.net/browse/JDK- 6425769

Otros consejos

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

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

No he probado esto, pero esto puede ayudar.

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

Además, no quería crear mi propio RMIServerSocketFactory con todos los complejidades asociadas con él, estaba buscando un parche simple para el código existente.

He solucionado esto parcheando la fábrica de zócalos JVM RMI predeterminada que es responsable de crear este socket del servidor. Ahora es compatible con el nuevo 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.

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

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 inicio 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 los puertos de escucha RMI aleatorios aún se unirán a todas las interfaces, pero eso está bien ya que siempre eligen un puerto libre de todos modos.

Ahora puede ejecutar varias 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);
  }

}

Acabo de intentarlo

-Dcom.sun.management.jmxremote.host =

con openjdk 1.8, y funciona bien. Se une a esa dirección (según netstat) y todo se ve bien (y funciona).

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

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

... así como ...

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

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top