2008-12-01 6 views
17

Ich starte gerade meine Java-VM mit den Eigenschaften com.sun.management.jmxremote.*, damit ich über JConsole eine Verbindung zur Verwaltung und Überwachung herstellen kann. Leider hört es auf allen Schnittstellen (IP-Adressen) auf der Maschine ab.Wie bindet JMX eine bestimmte Schnittstelle?

In unserer Umgebung gibt es häufig Fälle, in denen mehr als eine Java VM gleichzeitig auf einer Maschine ausgeführt wird. Es ist zwar möglich, JMX anzuweisen, verschiedene TCP-Ports zu hören (mit com.sun.management.jmxremote.port), aber es wäre schön, JMX stattdessen den JMX-Standardanschluss verwenden zu lassen und nur an eine bestimmte IP-Adresse zu binden (und nicht an alle).

Dies würde es viel einfacher machen herauszufinden, mit welcher VM wir über JConsole verbunden sind (da jede VM ihre eigene IP-Adresse "besitzt"). Hat jemand herausgefunden, wie JMX eine einzige IP-Adresse oder einen Hostnamen abhören kann?

Antwort

15

Wenn jemand anderes seine Nerven mit diesem ... Nach 10 Jahren wird verlieren, sie es endlich behoben!

Da Java 8u102 -Dcom.sun.management.jmxremote.host bindet an die ausgewählte IP-

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

8

Fernando stellte bereits einen Link zu my blog post :) ..es ist nicht trivial. Sie müssen einen eigenen RMIServerSocketFactoryImpl angeben, der Sockets auf der gewünschten Adresse erstellt.

Wenn interne/externe Schnittstellen das Problem sind und Sie lokalen Zugriff haben, kann das Einrichten einer lokalen Firewall einfacher sein.

+0

Danke - Ich habe nicht gedacht, es wäre einfach oder hübsch. :) –

-3

Die akzeptierte Antwort ist ziemlich alt. Es gibt einige Hinweise, dass Java jetzt einige Optionen bietet, um dies zu ermöglichen. Zum Beispiel habe ich gesehen:

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

... sowie ...

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

jedoch zumindest auf meinem System unter jdk 1.7, diese scheinen keine Wirkung zu haben - die Der JMX-Connector ist weiterhin an * gebunden. Eine aktualisierte Antwort (mit spezifischen anwendbaren Versionen) würde sehr geschätzt werden. Diese sollte einfach sein.

+0

Keines dieser Elemente steuert die Bind-Adresse. 'java.rmi.server.hostname' ist nicht neu, es ist seit 17 Jahren da, und ich bezweifle, dass der andere auch neu ist. – EJP

+0

Ich habe nicht gesagt, dass sie neu sind. Ich sagte, ich hätte sie gesehen und sie hätten nicht funktioniert. – sosiouxme

+0

Ich hatte gehofft, dass es einen Weg gibt, der wirklich funktioniert, ohne schrecklich zu sein. Hab aber keine gefunden. – sosiouxme

0

Ich habe das nicht versucht, aber das kann helfen.

Das Hauptproblem hier war, dass es keine einfache Möglichkeit gibt, die Host-IP Adresse für JMX zu binden, es würde immer an alle Schnittstellen binden. Die Eigenschaft 'java.rmi.server.hostname' funktionierte nicht und ich wollte nicht verschiedene Ports für alle verschiedenen Instanzen auf demselben Host auswählen.

Auch ich wollte meine eigene RMIServerSocketFactory mit allen Komplexitäten nicht erstellen, ich war nach einem einfachen Patch auf den vorhandenen Code.

Ich habe das behoben, indem ich die standardmäßige JVM RMI-Socket-Factory, die ist, verantwortlich für das Erstellen dieses Server-Sockets. Es unterstützt jetzt die neue Eigenschaft 'com.sun.management.jmxremote.host'.

Speichern Sie den folgenden Java-Code in einer Datei mit dem Namen sun/rmi/transport/proxy/RMIDirectSocketFactory.java.

Kompilieren und erstellen Sie jmx_patch.jar und legen Sie es in den Tomcat lib/ Ordner.

Anschließend müssen Sie die folgende Zeile in bin/setenv.sh hinzuzufügen:

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

in tomcat Instanz diese Option hinzufügen, starten

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

Dies wird dann nur die JMX-Dienst binden 192.168.100.100 zu adressieren. das 2 andere Zufall RMI listening-Ports wird immer noch an alle Schnittstellen binden, aber das ist in Ordnung als sie ohnehin immer einen freien Port wählen.

Sie können nun mehr tomcat-Instanzen auf einem einzigen Host mit allen Standard-Ports laufen intakt (zB 8080 für JMX für alle von ihnen).

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

Ich habe gerade versucht

-Dcom.sun.management.jmxremote.host =

mit openjdk 1,8, und es funktioniert gut. Es bindet sich an diese Adresse (nach Netstat) und alles sieht richtig aus (und funktioniert).

+0

Das ist eine doppelte Antwort - vielleicht wollten Sie der ursprünglichen Antwort einen Kommentar hinzufügen? – Richlv

Verwandte Themen