2008-12-01 9 views
17

Je démarre actuellement ma VM Java avec les propriétés com.sun.management.jmxremote.* afin que je puisse me connecter via JConsole pour la gestion et la surveillance. Malheureusement, il écoute toutes les interfaces (adresses IP) sur la machine.Comment lier JMX à une interface spécifique?

Dans notre environnement, il y a souvent des cas où plus d'une machine virtuelle Java s'exécute sur une machine en même temps. Bien qu'il soit possible de dire à JMX d'écouter sur différents ports TCP (en utilisant com.sun.management.jmxremote.port), il serait bien que JMX utilise plutôt le port JMX standard et se connecte simplement à une adresse IP spécifique (plutôt qu'à la totalité d'entre eux). Cela faciliterait grandement la détermination de la machine virtuelle à laquelle nous nous connectons via JConsole (puisque chaque machine virtuelle "possède" sa propre adresse IP). Est-ce que quelqu'un a trouvé comment faire écouter JMX sur une seule adresse IP ou nom d'hôte?

Répondre

15

Si quelqu'un d'autre va perdre ses nerfs avec cette ... Après 10 ans, ils ont finalement fixé le!

Depuis Java 8u102 -Dcom.sun.management.jmxremote.host se fixe à l'IP sélectionnée

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

8

Fernando a déjà fourni un lien vers my blog post :) .. ce n'est pas trivial. Vous devez fournir votre propre RMIServerSocketFactoryImpl qui crée des sockets sur l'adresse voulue.

Si les interfaces internes/externes constituent le problème et que vous disposez d'un accès local, un pare-feu local peut être plus facile.

+0

Merci - je ne pensais pas que ce serait simple ou joli. :) –

-3

La réponse acceptée est assez ancienne. Il y a quelques indications que Java fournit maintenant quelques options pour activer ceci. Par exemple, je l'ai vu:

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

... ainsi que ...

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

Cependant, au moins sur mon système sous JDK 1.7, ceux-ci ne semblent pas avoir d'effet - la Le connecteur JMX se lie toujours à *. Une réponse mise à jour (avec des versions spécifiques applicables) serait très appréciée. Ce devrait être simple.

+0

Aucun de ces contrôles l'adresse de liaison. 'java.rmi.server.hostname' n'est pas nouveau, il est là depuis 17 ans, et je doute que l'autre soit nouveau non plus. – EJP

+0

Je n'ai pas dit qu'ils étaient nouveaux. J'ai dit que je les avais vus et qu'ils ne travaillaient pas. – sosiouxme

+0

J'espérais qu'il y avait un moyen qui fonctionne réellement sans être horrible. N'en ai pas trouvé cependant. – sosiouxme

0

Je n'ai pas essayé ceci mais ceci peut aider.

la principale nuisance ici était qu'il n'y a pas de moyen facile de spécifier l'adresse IP hôte pour JMX à lier à, il se lierait toujours à toutes les interfaces. La propriété 'java.rmi.server.hostname' ne fonctionnait pas et je ne voulais pas choisir différents ports pour toutes les instances différentes sur le même hôte.

En outre, je ne voulais pas créer ma propre RMIServerSocketFactory avec toutes les complexités qui lui sont associés, j'étais après un simple patch au code existant.

J'ai résolu ce problème en corrigeant l'usine de socket JVM RMI par défaut qui est responsable de la création de cette socket serveur. Il prend désormais en charge la nouvelle propriété 'com.sun.management.jmxremote.host' . Enregistrez le code Java ci-dessous dans un fichier nommé sun/rmi/transport/proxy/RMIDirectSocketFactory.java pour que cela fonctionne.

Compilez et créez-y jmx_patch.jar et placez-le dans le dossier tomcat lib/ .

Vous devez alors ajouter la ligne suivante à bin/setenv.sh:

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

ajouter cette option dans l'instance tomcat démarrage

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

Cela lie alors le service JMX que pour répondre 192.168.100.100. les 2 autres aléatoires ports d'écoute RMI toujours se lier à toutes les interfaces, mais qui est bien comme toujours choisir un port libre de toute façon.

Vous pouvez maintenant exécuter plusieurs instances de tomcat sur un seul hôte avec tous les ports par défaut intact (par exemple 8080 pour JMX pour tous).

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

Je viens d'essayer

-Dcom.sun.management.jmxremote.host =

avec OpenJDK 1.8, et ça marche bien. Il se lie à cette addess (selon netstat) et tout semble correct (et fonctionne).

+0

C'est une réponse en double - peut-être que vous vouliez ajouter un commentaire à la réponse originale? – Richlv

Questions connexes