Zabbix Java JMX Monitoring

Was ist Java- und JMX-Monitoring?

JMX-Monitoring kann dazu genutzt werden, alle JMX-Zähler einer Java-Applikation zu messen. Java Management Extensions (JMX) sind eine vom Java Community Process (JSR-3) entwickelte Spezifikation zur Verwaltung und Überwachung von Java-Anwendungen. Über ein sogenanntes Java-Gateway kann der Zabbix-Server die JMX-Monitoring-Services ansprechen, Daten einer Java-Applikation auslesen und als Item speichern und verarbeiten.

Ein typischer Anwendungsfall ist das Überwachen des Speicherverbrauchs einer Java-Applikation bzw. des Java-Runtime-Environments, in dem die Applikation betrieben wird.

Java-Gateway und Java-Pollers

Zabbix-Java-Gateway

Das sogenannte Zabbix-Java-Gateway ist ein spezieller Poller-Prozess, welcher Daten per JMX abrufen kann. Anders als die bisher genannten Poller-Prozesse handelt es sich nicht um einen „internen“ Prozess innerhalb des Zabbix-Servers. Das Java-Gateway ist ein eigenständiger Daemon, der über einen TCP-Port Daten an den Zabbix-Server liefert. Das Java-Gateway ist Java-Software, die ein JRE benötigt.

Java-Gateway aktivieren

Um JMX-Monitoring nutzen zu können, müssen Sie das Zabbix-Java-Gateway installieren, welches in der Regel in der Standardinstallation nicht enthalten ist. Wenn Sie die DEB- oder RPM-Pakete von Zabbix LLC nutzen, installieren Sie das Java-Gateway wie folgt. Das Java-Gateway erfordert keine Konfiguration und kann sofort gestartet werden.

apt-get install zabbix-java-gateway    # Debian/Ubuntu
/etc/init.d/zabbix-java-gateway start  # Debian/Ubuntu
yum install zabbix-java-gateway        # Red Hat/CentOS
service zabbix-java-gateway start      # Red Hat/CentOS
systemctl enable zabbix-java-gateway       # Red Hat/CentOS

Wenn Sie den Zabbix-Server aus den Quellen kompiliert haben, müssen Sie das Java-Gateway ebenfalls kompilieren. Alle benötigten Dateien sind in den Zabbix-Quellen enthalten. Zum Kompilieren brauchen Sie ein Java-JDK.

apt-get install default-jre-headless openjdk-7-jdk # Debian, Ubuntu
yum install java-1.7.0-openjdk                     # Red Hat, CentOS
cd /usr/src/zabbix-2.2.3
./configure --enable-java --prefix=/opt/zabbix-java-gateway
make
make install

Sie sollten nun im Ordner /opt/zabbix-java-gateway/sbin/zabbix_java Start- und Shutdown-Skripte vorfinden.

cd /opt/zabbix-java-gateway/sbin/zabbix_java
./startup.sh

Testen Sie, ob das Java-Gateway läuft.

root@debian:/# ps aux|grep java
zabbix    6364  0.4  5.1 606808 25756 ?        Sl   22:12   0:00 /usr/bin/java -server -classpath /usr/sbin/zabbix_java/lib:/usr/sbin/zabbix_java/lib/logback-core-0.9.27.jar:/usr/sbin/zabbix_java/lib/org-json-2010-12-28.jar:/usr/sbin/zabbix_java/lib/slf4j-api-1.6.1.jar:/usr/sbin/zabbix_java/lib/logback-classic-0.9.27.jar:/usr/sbin/zabbix_java/bin/zabbix-java-gateway-2.2.3.jar -Dzabbix.pidFile=/var/run/zabbix/zabbix_java_gateway.pid com.zabbix.gateway.JavaGateway

Java-Gateway als Datenlieferant für den Zabbix-Server

Tragen Sie das Java-Gateway in die Datei /etc/zabbix/zabbix_server.conf ein. Aktivieren Sie im Zabbix-Server mindestens einen Java-Poller, der die Item-Daten beim Java-Gateway „anfragt“ und den Serverprozess weiterleitet. Starten Sie, nachdem Sie die Änderungen vorgenommen haben, den Zabbix-Server neu.

### Option: JavaGateway
#       IP address (or hostname) of Zabbix Java gateway.
#       Only required if Java pollers are started.
#
# Mandatory: no
# Default:
JavaGateway=127.0.0.1

### Option: JavaGatewayPort
#       Port that Zabbix Java gateway listens on.
#
# Mandatory: no
# Range: 1024-32767
# Default:
JavaGatewayPort=10052

### Option: StartJavaPollers
#       Number of pre-forked instances of Java pollers.
#
# Mandatory: no
# Range: 0-1000
# Default:
StartJavaPollers=2

JMX in einer Applikation aktivieren

Die Java Management Extensions sind bei Java-Programmen in der Regel deaktiviert. Das JMX-Interface wird pro Applikation aktiviert, wobei das JRE einen TCP-Port öffnet, über die andere JVMs, zum Beispiel das Zabbix-Java-Gateway, mit dem JMX-Interface kommunizieren können. JMX kann für alle Java-Programme aktiviert werden, die mit Java 5 oder höher gestartet werden. Starten Sie eine Java-Software mit den folgenden Optionen:

-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=<PORT> \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false

Beispiel Jedit

apfelmus:jedit thorsten$ java -Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=12345 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-jar jedit.jar 
Jedit mit aktiviertem JMX-Monitoring

Beispiel Tomcat

Ubuntu
Öffnen Sie die Datei /etc/default/tomcat7 oder /etc/default/tomcat8 mit einem Editor und erweitern Sie die Java-Optionen wie folgt. Nach einem Restart von Tomcat sollte JMX aktiviert sein.

# You may pass JVM startup parameters to Java here. If unset, the default
# options will be: -Djava.awt.headless=true -Xmx128m -XX:+UseConcMarkSweepGC
#
# Use "-XX:+UseConcMarkSweepGC" to enable the CMS garbage collector (improved
# response time). If you use that option and you run Tomcat on a machine with
# exactly one CPU chip that contains one or two cores, you should also add
# the "-XX:+CMSIncrementalMode" option.
JAVA_OPTS="-Djava.awt.headless=true -Xmx128m -XX:+UseConcMarkSweepGC"
JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote"
JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote.port=12345"
JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote.authenticate=false"
JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote.ssl=false"

CentOS/RHEL
Tragen Sie an das Ende der Datei /etc/sysconfig/tomcat folgendes ein:

JAVA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=12345 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false"

Windows
Im Systemtray finden Sie den Tomcat-Servicemanager. Klicken Sie auf "Configure" und wählen Sie den Reiter "Java" aus. Im Feld "Java Options" tragen Sie die folgenden vier zusätzlichen Zeilen ein.

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8091
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Wenn die Windows-Firewall aktiv ist, müssen Sie u.U. noch eine eingehende Regel erstellen, damit der Zabbix-Server auf den JMX-Port zugreifen darf.
Jmx für Tomcat unter Windows aktivieren

Starten Sie Tomcat neu. Das Kommando netstat -tulpen|grep 12345 sollte bestätigen, dass der TCP Port 12345 für das JMX-Monitoring nun lauscht.

Sollten Sie die Fehlermeldung

 "jmx "Connection refused to host: 127.0.1.1; nested exception" 

erhalten, erweitern Sie die Java-Startoptionen mit folgenden Parametern:

JAVA_OPTS="${JAVA_OPTS} -Djava.rmi.server.hostname=<HOST_IP>"
Jmx Fehlermeldung in Zabbix

Passwortschutz

Wenn Sie die JMX-Schnittstelle nicht für „Jedermann“ im Netzwerk öffnen möchten, können Sie ein Passwort für den Zugriff setzen. Zabbix ist in der Lage, eine Authentifizierung vorzunehmen.

Verwenden Sie zum Aktivieren eines passwortgeschützten JMX-Interface die folgenden Optionen beim Starten des Java-Programms:

-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=12345 \
-Dcom.sun.management.jmxremote.authenticate=true \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.access.file=/etc/jmx.access \
-Dcom.sun.management.jmxremote.password.file=/etc/jmx.password \

# /etc/jmx.access
zabbix readonly

# /etc/jmx.password
zabbix geheim

Die Datei /etc/jmx.password muss dem Benutzer gehören, mit dessen Rechten das zu überwachende Java-Programm gestartet wird, und nur dieser User darf Leserechte auf diese Datei haben. Wenn Sie das Monitoring von Tomcat mit einem Passwort schützen möchten, führen Sie Folgendes aus:

chown tomcat7 /etc/jmx.password
chmod 0500 /etc/jmx.password

In der Konfiguration der Items tragen Sie dann den Benutzernamen und das gesetzte Passwort ein. Empfehlenswert ist es, Benutzername und Passwort in ein Makro zu speichern, damit Sie pro Host unterschiedliche Zugangsdaten verwenden können und keine Zugangsdaten in Templates hart hinterlegen müssen.

JMX-CPU-Monitoring mit Passwortschutz

Wenn Sie eine SSL-Verschlüsselung beim Java-Monitoring verwenden wollen, finden Sie in der Oracle-Dokumentation Hinweise, wie Sie diese einrichten.

JMX-Items einrichten

Bevor Sie Daten vom JMX-Interface abrufen, müssen Sie pro Host angeben, auf welcher IP-Adresse und auf welchem TCP-Port das JMX-Interface des Java-Programmes lauscht. Navigieren Sie zur Hostkonfiguration und fügen Sie ein JMX-Interface hinzu. Wenn Sie auf einem Host mehrere Java-Programme per JMX überwachen möchten, müssen Sie unterschiedliche TCP-Ports verwenden.

Hinzufügen eines JMX-Interface

Sobald Sie ein JMX-Interface für einen Host hinzugefügt haben, können Sie wie gewohnt Items einrichten. Als Typ wählen Sie „JMX Agent“ aus. Testen Sie das JMX-Monitoring zum Beispiel mit den folgenden Item-Keys:

  • jmx["java.lang:type=Memory","HeapMemoryUsage.used"] Liefert den Speicherverbrauch der überwachten Applikation in Bytes.
  • jmx["java.lang:type=OperatingSystem","ProcessCpuLoad"] Liefert den CPU-Verbrauch des überwachten Prozesses als Dezimalfaktor. Verwenden Sie „Use custom multiplier=100“, um den CPU-Verbrauch in Prozent zu messen.
JMX-Item

Beispiele von JMX-Monitoring-Objekten

Heap space in Java?

Wenn ein Java-Programm in einer virtuellen Maschine (JRE) gestartet wird, erhält dieses Hauptspeicher vom Betriebssystem. Die JVM verwendet nur diesen zugewiesenen Speicher für alle Anforderungen des Programms. Ein Teil dieses Speichers wird Heap-Speicher genannt. Objekte verwenden diesen Speicher, und der sogenannte Garbage-Collector gibt diesen Speicher wieder frei. Per JMX können Sie den freien und verbrauchten Heap-Speicher einzelner Programme überwachen.

Wichtige Parameter eines Java-Prozesses

Wichtige Parameter eines Java-Prozesses
ObjectName Attributes
java.lang:type=ClassLoading LoadedClassCount
java.lang:type=GarbageCollector,name=ConcurrentMarkSweep CollectionTime
CollectionCount
java.lang:type=GarbageCollector,name=ParNew CollectionTime
CollectionCount
java.lang:type=Memory HeapMemoryUsage.commited

HeapMemoryUsage.used
HeapMemoryUsage.max
NonHeapMemoryUsage.commited
NonHeapMemoryUsage.used
NonHeapMemoryUsage.max

java.lang:type=OperatingSystem ProcessCpuLoad
java.lang:type=Threading ThreadCount