Running Multiple Tomcat Instances with JMX Monitoring and Zabbix Integration
Running multiple Tomcat instances on a single host requires careful port management and service isolation. This setup demonstrates deploying two additional instances alongside a primary installation, followed by JMX monitoring configuration and Zabbix integration using containerized infrastructure.
Multi-Instance Deploymennt
Extract the baseline installation and replicate it for independent instances:
cd /opt/tomcat
tar -xzf apache-tomcat-9.0.80.tar.gz
mv apache-tomcat-9.0.80 baseline
rsync -av baseline/ instance-alpha/
rsync -av baseline/ instance-beta/
Configure unique ports for each instance to prevent conflicts:
# Instance Alpha: HTTP 9081, Shutdown 9005
sed -i 's/8080/9081/g' instance-alpha/conf/server.xml
sed -i 's/8005/9005/g' instance-alpha/conf/server.xml
# Instance Beta: HTTP 9082, Shutdown 9006
sed -i 's/8080/9082/g' instance-beta/conf/server.xml
sed -i 's/8005/9006/g' instance-beta/conf/server.xml
Create systemd unit files for service management:
cat > /etc/systemd/system/tomcat-alpha.service << 'EOF'
[Unit]
Description=Tomcat Instance Alpha
After=network.target
[Service]
Type=forking
Environment="JAVA_HOME=/usr/lib/jvm/java-11-openjdk"
Environment="CATALINA_HOME=/opt/tomcat/instance-alpha"
Environment="CATALINA_PID=/opt/tomcat/instance-alpha/temp/tomcat.pid"
ExecStart=/opt/tomcat/instance-alpha/bin/startup.sh
ExecStop=/opt/tomcat/instance-alpha/bin/shutdown.sh
ExecReload=/bin/sh -c '/opt/tomcat/instance-alpha/bin/shutdown.sh && sleep 3 && /opt/tomcat/instance-alpha/bin/startup.sh'
[Install]
WantedBy=multi-user.target
EOF
cat > /etc/systemd/system/tomcat-beta.service << 'EOF'
[Unit]
Description=Tomcat Instance Beta
After=network.target
[Service]
Type=forking
Environment="JAVA_HOME=/usr/lib/jvm/java-11-openjdk"
Environment="CATALINA_HOME=/opt/tomcat/instance-beta"
Environment="CATALINA_PID=/opt/tomcat/instance-beta/temp/tomcat.pid"
ExecStart=/opt/tomcat/instance-beta/bin/startup.sh
ExecStop=/opt/tomcat/instance-beta/bin/shutdown.sh
ExecReload=/bin/sh -c '/opt/tomcat/instance-beta/bin/shutdown.sh && sleep 3 && /opt/tomcat/instance-beta/bin/startup.sh'
[Install]
WantedBy=multi-user.target
EOF
Reload systemd and enable auto-start:
systemctl daemon-reload
systemctl enable --now tomcat-alpha tomcat-beta
Verify deployment by creating test resources:
echo "<h1>Alpha Instance</h1>" > /opt/tomcat/instance-alpha/webapps/ROOT/status.jsp
echo "<h1>Beta Instance</h1>" > /opt/tomcat/instance-beta/webapps/ROOT/status.jsp
Access via http://host:9081/status.jsp and http://host:9082/status.jsp.
JMX Monitoring Configuration
Enable remote JMX monitoring on the primary instance by modifying startup parameters:
vi /opt/tomcat/baseline/bin/catalina.sh
Add the following to CATALINA_OPTS (ensure continuous line or proper line continuation):
CATALINA_OPTS="${CATALINA_OPTS} \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=23456 \
-Dcom.sun.management.jmxremote.rmi.port=23457 \
-Dcom.sun.management.jmxremote.authenticate=true \
-Dcom.sun.management.jmxremote.password.file=/opt/tomcat/baseline/conf/jmx.credentials \
-Dcom.sun.management.jmxremote.access.file=/opt/tomcat/baseline/conf/jmx.acl \
-Dcom.sun.management.jmxremote.ssl=false \
-Djava.rmi.server.hostname=10.0.0.50"
Configure authentication files:
cd /opt/tomcat/baseline/conf
echo "monitoruser securePass123" > jmx.credentials
echo "monitoruser readonly" > jmx.acl
chmod 600 jmx.credentials jmx.acl
systemctl restart tomcat
Verify connectivity using jconsole from a workstation with JDK installed, connecting to 10.0.0.50:23456 with credentials above.
Zabbix Container Integration
When deploying Zabbix via Docker, the Java Gateway requires explicit configuration. If encountering "JVM is not reachable" errors, verify the Java poller configuration.
For existing containers, modify the server configuration:
docker exec -it zabbix-server /bin/bash
vi /etc/zabbix/zabbix_server.conf
Set required parameters:
JavaGateway=zabbix-java-gateway
JavaGatewayPort=10052
StartJavaPollers=5
Restart the container:
docker restart zabbix-server
Alternatively, configure during initial deployment with environment variables:
docker run -d \
--name zabbix-server \
--network monitoring-net \
-e DB_SERVER_HOST="zabbix-db" \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="db_secret" \
-e ZBX_JAVAGATEWAY_ENABLE="true" \
-e ZBX_JAVAGATEWAY="zabbix-java-gateway" \
-e ZBX_JAVAGATEWAYPORT="10052" \
-e ZBX_START_POLLERS="5" \
-p 10051:10051 \
zabbix/zabbix-server-mysql:alpine-6.0-latest
Troubleshooting
Active check configuration failures
If agents report timeout errors retrieving configuration from [zabbix-server]:10051, verify host firewall rules allow bidirectional communication on the Zabbbix port.
JVM unreachable errors
- Verify Tomcat service status:
systemctl status tomcat - Confirm Java Gateway container is running:
docker ps | grep java-gateway - Validate JMX port accessibility:
nc -zv tomcat-host 23456
Protocol header errors Warnings regarding "bad protocol header: 53 53 48 2D 32" in gateway logs typically indicate SSH probes or port scanning rather than actual JMX connectivity issues. These may be ignored if caused by network security scans.