An active-active Tomcat setup keeps multiple application instances available so incoming traffic can be balanced across nodes and a single host failure does not become an outage.
In a Pacemaker / Corosync cluster managed with pcs, a systemd unit can be registered as a cluster resource and monitored for health. Cloning that resource runs an instance on each eligible node, while the cluster tracks failures and restarts the unit when monitoring detects a problem.
Cluster control changes the normal service lifecycle, so the underlying Tomcat unit should remain disabled in systemd and only started through the cluster. Active-active does not replicate deployments or runtime state, so application files and configuration must be identical on every node and session state or uploads should use a shared backend or load balancer stickiness. Production clusters typically require fencing (STONITH) and a load balancer with health checks, since pcs does not distribute traffic.
$ sudo pcs status Cluster name: clustername Cluster Summary: * Stack: corosync (Pacemaker is running) * Current DC: node-01 (version 2.1.6-6fdc9deea29) - partition with quorum * 3 nodes configured * 0 resource instances configured ##### snipped #####
$ systemctl list-unit-files --type=service | grep -E '^tomcat.*\.service' tomcat10.service disabled enabled
Strip the trailing .service when using the systemd: resource type.
$ sudo systemctl disable --now tomcat10.service
Leaving Tomcat enabled in systemd can start it automatically at boot even when the cluster intends it to be stopped, causing conflicting state and confusing resource status.
$ sudo pcs resource create tomcat_service systemd:tomcat10 op monitor interval=30s
Use systemd:tomcat10 when that unit is present.
Related: How to create a Pacemaker resource
$ sudo pcs resource clone tomcat_service clone-max=2 clone-node-max=1
Omit clone-max to start an instance on every cluster node by default.
$ sudo pcs status resources
* Clone Set: tomcat_service-clone [tomcat_service]:
* Started: [ node-01 node-02 ]
$ sudo ss --listening --numeric --tcp --processes 'sport = :8080'
State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0 100 *:8080 *:* users:(("java",pid=220191,fd=38))
Replace 8080 with the port configured by the Connector in server.xml.
Session-dependent applications require sticky sessions or an external session store to avoid user logouts when requests move between nodes.