13 JMX-Überwachung

Übersicht

JMX-Monitoring kann verwendet werden, um JMX-Zähler einer Java-Anwendung zu überwachen.

JMX-Monitoring wird in Zabbix nativ unterstützt, und zwar in Form eines Zabbix-Daemons namens „Zabbix Java gateway“.

Um den Wert eines bestimmten JMX-Zählers auf einem Host abzurufen, fragt der Zabbix Server das Zabbix Java gateway ab, das wiederum die JMX-Management-API verwendet, um die betreffende Anwendung remote abzufragen.

Weitere Details und Informationen zur Einrichtung finden Sie im Abschnitt Zabbix Java gateway.

Die Kommunikation zwischen dem Java gateway und der überwachten JMX-Anwendung sollte nicht durch eine Firewall blockiert werden.

Aktivierung der Remote-JMX-Überwachung für eine Java-Anwendung

Für eine Java-Anwendung muss keine zusätzliche Software installiert werden, sie muss jedoch mit den unten angegebenen Befehlszeilenoptionen gestartet werden, damit die Remote-JMX-Überwachung unterstützt wird.

Als absolutes Minimum können Sie, wenn Sie einfach mit der Überwachung einer einfachen Java-Anwendung auf einem lokalen Host ohne erzwungene Sicherheitsmaßnahmen beginnen möchten, sie mit diesen Optionen starten:

java \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=12345 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.registry.ssl=false \
-jar /path/to/your/application.jar

Dadurch lauscht Java auf eingehende JMX-Verbindungen an Port 12345, nur vom lokalen Host aus, und es wird festgelegt, dass weder Authentifizierung noch SSL erforderlich sind.

Wenn Sie Verbindungen über eine andere Schnittstelle zulassen möchten, setzen Sie den Parameter -Djava.rmi.server.hostname auf die IP-Adresse dieser Schnittstelle.

Wenn Sie strengere Sicherheitsanforderungen umsetzen möchten, stehen Ihnen viele weitere Java-Optionen zur Verfügung. Im nächsten Beispiel wird die Anwendung beispielsweise mit einem vielseitigeren Satz von Optionen gestartet und für ein größeres Netzwerk geöffnet, nicht nur für den lokalen Host.

java \
-Djava.rmi.server.hostname=192.168.3.14 \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=12345 \
-Dcom.sun.management.jmxremote.authenticate=true \
-Dcom.sun.management.jmxremote.password.file=/etc/java-6-openjdk/management/jmxremote.password \
-Dcom.sun.management.jmxremote.access.file=/etc/java-6-openjdk/management/jmxremote.access \
-Dcom.sun.management.jmxremote.ssl=true \
-Dcom.sun.management.jmxremote.registry.ssl=true \
-Djavax.net.ssl.keyStore=$YOUR_KEY_STORE \
-Djavax.net.ssl.keyStorePassword=$YOUR_KEY_STORE_PASSWORD \
-Djavax.net.ssl.trustStore=$YOUR_TRUST_STORE \
-Djavax.net.ssl.trustStorePassword=$YOUR_TRUST_STORE_PASSWORD \
-Dcom.sun.management.jmxremote.ssl.need.client.auth=true \
-jar /path/to/your/application.jar

Die meisten (wenn nicht alle) dieser Einstellungen können in $JRE/lib/management/management.properties angegeben werden (oder dort, wo sich diese Datei auf Ihrem System befindet).

Beachten Sie, dass Sie, wenn Sie SSL verwenden möchten, das Skript startup.sh ändern müssen, indem Sie die Optionen -Djavax.net.ssl.* zum Java gateway hinzufügen, damit es weiß, wo sich Schlüssel- und Truststores befinden.

Eine ausführliche Beschreibung finden Sie unter Monitoring and Management Using JMX.

Konfiguration von JMX-Schnittstellen und Datenpunkten im Zabbix Frontend

Wenn der Java gateway läuft, der Server weiß, wo er ihn finden kann, und eine Java-Anwendung mit Unterstützung für die entfernte JMX-Überwachung gestartet wurde, ist es an der Zeit, die Schnittstellen und Datenpunkte in der Zabbix-GUI zu konfigurieren.

Konfigurieren der JMX-Schnittstelle

Sie beginnen damit, auf dem gewünschten Host eine Schnittstelle vom Typ JMX zu erstellen.

Alle obligatorischen Eingabefelder sind mit einem roten Sternchen markiert.

JMX-Agent-Datenpunkt hinzufügen

Für jeden JMX-Zähler, der Sie interessiert, fügen Sie einen JMX-Agent-Datenpunkt hinzu, der an diese Schnittstelle angehängt ist.\

Der Schlüssel im Screenshot unten lautet jmx["java.lang:type=Memory","HeapMemoryUsage.used"].

Alle erforderlichen Eingabefelder sind mit einem roten Sternchen markiert.

Die Felder, die für JMX-Datenpunkte spezifische Informationen erfordern, sind:

Typ Stellen Sie hier JMX-Agent ein.
Schlüssel Der Datenpunktschlüssel jmx[] enthält drei Parameter:
Objektname - der Objektname einer MBean
Attributname - ein MBean-Attributname mit optionalen zusammengesetzten Datenfeldnamen, die durch Punkte getrennt sind
eindeutige Kurzbeschreibung - eine eindeutige Beschreibung, die mehrere JMX-Datenpunkte mit demselben Objektnamen und Attributnamen auf dem Host ermöglicht (optional)
Weitere Details zu JMX-Datenpunktschlüsseln finden Sie unten.
Sie können MBeans und MBean-Attribute mit einem jmx.discovery[]-Low-Level-Discovery-Datenpunkt ermitteln.
JMX-Endpunkt Sie können einen benutzerdefinierten JMX-Endpunkt angeben. Stellen Sie sicher, dass die Verbindungsparameter des JMX-Endpunkts mit der JMX-Schnittstelle übereinstimmen. Dies kann durch die Verwendung von {HOST.*}-Makros erreicht werden, wie im Standard-JMX-Endpunkt.
{HOST.*}-Makros und Benutzermakros werden unterstützt.
Benutzername Geben Sie den Benutzernamen an (bis zu 255 Zeichen), falls Sie die Authentifizierung für Ihre Java-Anwendung konfiguriert haben.
Benutzermakros werden unterstützt.
Passwort Geben Sie das Passwort an (bis zu 255 Zeichen), falls Sie die Authentifizierung für Ihre Java-Anwendung konfiguriert haben.
Benutzermakros werden unterstützt.

Wenn Sie einen booleschen Zähler überwachen möchten, der entweder „true“ oder „false“ ist, geben Sie als Informationstyp „Numerisch (Ganzzahl ohne Vorzeichen)“ an und wählen im Reiter „Vorverarbeitung“ den Vorverarbeitungsschritt „Boolesch in Dezimal“ aus. Der Server speichert boolesche Werte dann jeweils als 1 oder 0.

JMX-Datenpunktschlüssel im Detail

Einfache Attribute

Ein MBean-Objektname ist nichts weiter als eine Zeichenkette, die Sie in Ihrer Java-Anwendung definieren. Ein Attributname hingegen kann komplexer sein. Falls ein Attribut einen primitiven Datentyp zurückgibt (eine Ganzzahl, eine Zeichenkette usw.), gibt es nichts, worüber man sich Sorgen machen müsste; der Schlüssel sieht dann wie folgt aus:

jmx[com.example:Type=Hello,weight]

In diesem Beispiel ist der Objektname „com.example:Type=Hello“, der Attributname „weight“ und der Typ des zurückgegebenen Werts sollte wahrscheinlich „Numerisch (Gleitkommazahl)“ sein.

Attribute, die zusammengesetzte Daten zurückgeben

Es wird komplizierter, wenn Ihr Attribut zusammengesetzte Daten zurückgibt. Zum Beispiel: Ihr Attributname ist „apple“ und es gibt einen Hash zurück, der seine Parameter wie „weight“, „color“ usw. darstellt. Ihr Schlüssel kann dann wie folgt aussehen:

jmx[com.example:Type=Hello,apple.weight]

So werden ein Attributname und ein Hash-Schlüssel voneinander getrennt, nämlich durch die Verwendung eines Punkts. Genauso werden, wenn ein Attribut verschachtelte zusammengesetzte Daten zurückgibt, die Teile durch einen Punkt getrennt:

jmx[com.example:Type=Hello,fruits.apple.weight]
Attribute, die tabellarische Daten zurückgeben

Attribute für tabellarische Daten bestehen aus einem oder mehreren zusammengesetzten Attributen. Wenn ein solches Attribut im Parameter für den Attributnamen angegeben wird, gibt dieser Datenpunkt den vollständigen Aufbau des Attributs im JSON-Format zurück. Die Werte der einzelnen Elemente innerhalb des Attributs mit tabellarischen Daten können mithilfe der Vorverarbeitung abgerufen werden.

Beispiel für ein Attribut mit tabellarischen Daten:

 jmx[com.example:type=Hello,foodinfo]

Datenpunktwert:

[
  {
    "a": "apple",
    "b": "banana",
    "c": "cherry"
  },
  {
    "a": "potato",
    "b": "lettuce",
    "c": "onion"
  }
]
Problem mit Punkten

So weit, so gut. Aber was ist, wenn ein Attributname oder ein Hash-Schlüssel ein Punktsymbol enthält? Hier ist ein Beispiel:

jmx[com.example:Type=Hello,all.fruits.apple.weight]

Das ist ein Problem. Wie teilt man Zabbix mit, dass der Attributname „all.fruits“ und nicht nur „all“ ist? Wie unterscheidet man einen Punkt, der Teil des Namens ist, von dem Punkt, der einen Attributnamen und Hash-Schlüssel trennt?

Das ist möglich; alles, was Sie tun müssen, ist, die Punkte, die Teil des Namens sind, mit einem Backslash zu maskieren:

jmx[com.example:Type=Hello,all\.fruits.apple.weight]

Auf die gleiche Weise maskieren Sie einen Punkt in Ihrem Hash-Schlüssel:

jmx[com.example:Type=Hello,all\.fruits.apple.total\.weight]
Andere Probleme

Ein Backslash-Zeichen in einem Attributnamen sollte maskiert werden:

jmx[com.example:type=Hello,c:\\documents]

Informationen zur Behandlung anderer Sonderzeichen im JMX-Datenpunktschlüssel finden Sie im Abschnitt zum Format des Datenpunktschlüssels section.

Das ist tatsächlich schon alles. Viel Erfolg beim JMX-Monitoring!

Nicht-primitive Datentypen

Es ist möglich, mit benutzerdefinierten MBeans zu arbeiten, die nicht-primitive Datentypen zurückgeben und die Methode toString() überschreiben.

Verwendung eines benutzerdefinierten Endpunkts mit JBoss EAP 6.4

Benutzerdefinierte Endpunkte ermöglichen die Arbeit mit anderen Transportprotokollen als dem standardmäßigen RMI.

Um diese Möglichkeit zu veranschaulichen, versuchen wir als Beispiel, das Monitoring von JBoss EAP 6.4 zu konfigurieren. Zunächst treffen wir einige Annahmen:

  • Sie haben das Zabbix Java gateway bereits installiert. Falls nicht, können Sie dies gemäß der Dokumentation tun.
  • Zabbix Server und Java gateway sind mit dem Präfix /usr/local/ installiert
  • JBoss ist bereits in /opt/jboss-eap-6.4/ installiert und läuft im Standalone-Modus
  • Wir gehen davon aus, dass alle diese Komponenten auf demselben Host arbeiten
  • Firewall und SELinux sind deaktiviert (oder entsprechend konfiguriert)

Nehmen wir einige einfache Einstellungen in zabbix_server.conf vor:

JavaGateway=127.0.0.1
StartJavaPollers=5

Und in der Konfigurationsdatei zabbix_java/settings.sh (oder zabbix_java_gateway.conf):

START_POLLERS=5

Prüfen Sie, dass JBoss auf seinem standardmäßigen Management-Port lauscht:

$ netstat -natp | grep 9999
tcp        0      0 127.0.0.1:9999          0.0.0.0:*               LISTEN      10148/java

Erstellen wir nun in Zabbix einen Host mit der JMX-Schnittstelle 127.0.0.1:9999.

Da wir wissen, dass diese Version von JBoss das Protokoll JBoss Remoting anstelle von RMI verwendet, können wir den Parameter JMX endpoint für Datenpunkte in unserer JMX-Vorlage entsprechend per Massenaktualisierung ändern:

service:jmx:remoting-jmx://{HOST.CONN}:{HOST.PORT}

Aktualisieren wir den Konfigurations-Cache:

/usr/local/sbin/zabbix_server -R config_cache_reload

Beachten Sie, dass zunächst ein Fehler auftreten kann.

„Unsupported protocol: remoting-jmx“ bedeutet, dass das Java gateway nicht weiß, wie es mit dem angegebenen Protokoll arbeiten soll. Dies kann behoben werden, indem eine Datei ~/needed_modules.txt mit folgendem Inhalt erstellt wird:

jboss-as-remoting
jboss-logging
jboss-logmanager
jboss-marshalling
jboss-remoting
jboss-sasl
jcl-over-slf4j
jul-to-slf4j-stub
log4j-jboss-logmanager
remoting-jmx
slf4j-api
xnio-api
xnio-nio

und anschließend der folgende Befehl ausgeführt wird:

for i in $(cat ~/needed_modules.txt); do find /opt/jboss-eap-6.4 -iname "${i}*.jar" -exec cp '{}' /usr/local/sbin/zabbix_java/lib/ \; ; done

Damit verfügt das Java gateway über alle erforderlichen Module für die Arbeit mit jmx-remoting. Anschließend muss nur noch das Java gateway neu gestartet werden. Warten Sie dann einen Moment, und wenn Sie alles richtig gemacht haben, werden JMX-Monitoring-Daten in Zabbix eintreffen (siehe auch: Neueste Daten).