The Tomcat Web container provides a native clustering solution that can be configured through Geronimo using gbean definitions within config.xml
or using server.xml
starting from v2.2 just like you did for a standalone Tomcat server. This document will go through the available GBeans and how to configure them for clustering in a Geronimo server with a tomcat web container.
Cluster Configuration Elements
Following are parameters or attributes you will need to configure for a Tomcat native clustering.
- Cluster
- ClusterListenerChain
- TomcatValveChain
- Channel
- Membership
- Receiver
- Sender
- ChannelInterceptor
- StaticMember
- ClusterManager
Although sufficient for many applications, Tomcat clusters have some limitations.
- This feature does not replicate stateful session Enterprise JavaBeans (EJBs). You will have to avoid stateful session EJBs in your distributed applications.
- This feature does not replicate dynamic updates to the Java Naming and Directory Interface (JNDI). You will have to configure all the JNDI names used by your distributed applications in every node of the cluster.
- This feature does not replicate distributable Web applications to other nodes in the cluster. You will have to deploy your distributable Web applications to every node.
A cluster configuration should be considered when you want to improve the scalability and availability of your Web application. The following sections provide detailed instructions on how to set up your cluster nodes.
Setting up a clustering environment
Generally, to set up a small cluster you will need at least 2 nodes and 1 HTTP server. The HTTP server is used to serve requests from clients and ensure well-balanced traffic load among different nodes. Similarly, each node is configured to use the same logical Tomcat engine and enable session affinity.
Planning your cluster
The Tomcat cluster replicates HTTP session data via memory to memory multicast communication.
Every node transmits its session data to every node in the cluster. This algorithm is only efficient when the clusters are small. If the clusters grow too large, the overhead in storage utilization and network traffic becomes excessive. To avoid excessive overhead, consider dividing your nodes into several smaller clusters.
HTTP session data is replicated among the nodes in the cluster using a multicast broadcast. All nodes in the cluster must be on the same physical subnet and multicast broadcast must be supported by that subnet.
Preparing your Web application
To participate in a cluster configuration, your Web application must be implemented correctly.
- Ensure that every object placed in the HTTP session implements java.io.Serializable. The clustering feature serializes the objects when it distributes them to the other nodes in the cluster.
- The deployment descriptor for your Web application, that is the
web.xml
file in the Web archive, must indicate that your Web application is distributable. To do this, insert the distributable element in the deployment descriptor.Excerpt from web.xml<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name> ... </display-name> <description> ... </description> <distributable> <distributable/> ... </web-app>
- Do not use stateful session Enterprise JavaBeans (EJBs). The clustering feature does not replicate stateful EJBs among the nodes in the cluster.
- If your Web application uses a database, make sure the database can be accessed from every node in the cluster. Ensure that the proper JDBC drivers are installed on every node and that the datasource objects are defined correctly on every node.
- Do not depend on dynamic updates to the Java Naming and Directory Interface (JNDI). You will need to configure all the JNDI names used by your application in every node of the cluster. The clustering feature does not replicate JNDI changes among the nodes in the cluster.
Enabling session affinity
Support for session affinity, also known as sticky session support, allows a load balancing service to route an HTTP request back to the same node that created the HTTP session associated with that request until that node fails. You must use session affinity if you configure an asynchronous type of session replication. With asynchronous replication, the reply is returned before the HTTP session is replicated so there is always a chance that the next request using that session arrives before the replication is complete. In this case, the only way to ensure that the request is processed using the correct session data is to route the request to the node that sent the reply to the last request and originated the replication.
In Geronimo v2.2, users can have the same experiences as in Tomcat Web container to configure session affinity. To enable session affinity, you must modify servel.xml
under <GERONIMO_HOME>/var/catalina
directory and configure the <Engine> with a jvmRoute attribute value that is unique for each node in the cluster. The load balancer will return this value in the session cookie or the encoded URL returned to the browser. When a related request arrives it can use the value to route the request to the correct node. See
- For every node in the cluster, update
server.xml
as followed after the server is stopped:whereExcerpt from server.xml... <Engine name="Catalina" defaultHost="${ServerHostname}" jvmRoute="nodeId"> ...
- nodeId is a node identifier that is unique among all the nodes in the cluster. If you are using mod_jk, make sure that the jvmRoute attribute value matches your worker name in
workers.properties
.
- nodeId is a node identifier that is unique among all the nodes in the cluster. If you are using mod_jk, make sure that the jvmRoute attribute value matches your worker name in
- Restart the server to enable the new configuration.
Engaging load balancing and failover
Initially, the server configuration includes an AJP connector suitable for exchanging messages with a load balancing service. See Configuring a remote Apache HTTP server for more information about the HTTP server configuration.
Configuring the cluster at application level
To configure applicaiton level clustering, you have to input all related GBean settings in your deployment plan to make sure HTTP sessions are replicated successfully, cluster configuration elements of Tomcat Web containers must be configured using gbean definitions within deployment plans. If you want to deploy your Web application to a cluster, install your WAR files to the appropriate cluster member, assuring that you use the correct deployment plan for each member.
Sample Tomcat clustering with multicast Configuration
Here is the template for your Web application deployment plan. See Creating deployment plans for Web applications for more information about the parameters.
<web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web/tomcat-1.2" xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2"> <dep:environment> <dep:moduleId> <dep:groupId>org.mygroup</dep:groupId> <dep:artifactId>web-cluster-server1</dep:artifactId> <dep:version>2.2</dep:version> <dep:type>war</dep:type> </dep:moduleId> <dep:dependencies> <dep:dependency> <dep:groupId>console.realm</dep:groupId> <dep:artifactId>geronimo-properties-realm</dep:artifactId> <dep:version>1.0</dep:version> <dep:type>car</dep:type> </dep:dependency> </dep:dependencies> <dep:hidden-classes/> <dep:non-overridable-classes/> </dep:environment> <context-root>/servlet-examples-cluster</context-root> <security-realm-name>geronimo-properties-realm</security-realm-name> <security> <default-principal> <principal name="anonymous" class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal"/> </default-principal> <role-mappings> <role role-name="tomcat"> <principal name="admin" class="org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal"/> </role> </role-mappings> </security> <cluster>TomcatCluster</cluster> <gbean class="org.apache.geronimo.tomcat.cluster.CatalinaClusterGBean" name="TomcatCluster"> <attribute name="className">org.apache.catalina.ha.tcp.SimpleTcpCluster</attribute> <attribute name="initParams"/> <reference name="ClusterManager"> <name>TomcatClusterManager</name> </reference> <reference name="TomcatValveChain"> <name>ReplicationValve</name> </reference> <reference name="ClusterListenerChain"> <name>ClusterSessionListener</name> </reference> <reference name="Channel"> <name>TomcatGroupChannel</name> </reference> </gbean> <!-- Cluster Manager --> <gbean name="TomcatClusterManager" class="org.apache.geronimo.tomcat.cluster.ClusterManagerGBean"> <attribute name="className">org.apache.catalina.ha.session.DeltaManager</attribute> <attribute name="initParams">name=${clusterName} channelSendOptions=6 expireSessionsOnShutdown=false notifyListenersOnReplication=true mapSendOptions=6</attribute> </gbean> <!-- Cluster Channel --> <gbean class="org.apache.geronimo.tomcat.cluster.ChannelGBean" name="TomcatGroupChannel"> <attribute name="className">org.apache.catalina.tribes.group.GroupChannel</attribute> <attribute name="initParams"/> <reference name="Membership"> <name>TomcatMembership</name> </reference> <reference name="Receiver"> <name>TomcatReceiver</name> </reference> <reference name="Sender"> <name>TomcatSender</name> </reference> <reference name="ChannelInterceptor"> <name>TomcatChannelInterceptor</name> </reference> </gbean> <!-- Cluster Membership --> <gbean class="org.apache.geronimo.tomcat.cluster.MembershipServiceGBean" name="TomcatMembership"> <attribute name="className">org.apache.catalina.tribes.membership.McastService</attribute> <attribute name="initParams"> mcastAddr=228.0.0.4 mcastPort=45564 mcastFrequency=500 mcastDropTime=3000 </attribute> </gbean> <!-- Cluster Receiver --> <gbean class="org.apache.geronimo.tomcat.cluster.ReceiverGBean" name="TomcatReceiver"> <attribute name="className">org.apache.catalina.tribes.transport.nio.NioReceiver</attribute> <attribute name="initParams"> tcpListenAddress=auto tcpListenPort=4001 tcpSelectorTimeout=100 tcpThreadCount=6 </attribute> </gbean> <!-- Cluster Sender --> <gbean class="org.apache.geronimo.tomcat.cluster.SenderGBean" name="TomcatSender"> <attribute name="className">org.apache.catalina.tribes.transport.ReplicationTransmitter</attribute> <attribute name="initParams"> replicationMode=pooled waitForAck=true </attribute> </gbean> <!-- Cluster Valves--> <gbean class="org.apache.geronimo.tomcat.ValveGBean" name="ReplicationValve"> <attribute name="className">org.apache.catalina.ha.tcp.ReplicationValve</attribute> <attribute name="initParams">filter=.*\.gif;.*\.js;.*\.css;.*\.png;.*\.jpeg;.*\.jpg;.*\.htm;.*\.html;.*\.txt;</attribute> <reference name="NextValve"> <name>JvmRouteBinderValve</name> </reference> </gbean> <!-- Cluster Route Binder --> <gbean class="org.apache.geronimo.tomcat.ValveGBean" name="JvmRouteBinderValve"> <attribute name="className">org.apache.catalina.ha.session.JvmRouteBinderValve</attribute> <attribute name="initParams">enabled=true</attribute> </gbean> <!-- Cluster Listener --> <gbean class="org.apache.geronimo.tomcat.cluster.ClusterListenerGBean" name="ClusterSessionListener"> <attribute name="className">org.apache.catalina.ha.session.ClusterSessionListener</attribute> <reference name="NextListener"> <name>JvmRouteSessionIDBinderListener</name> </reference> </gbean> <!-- Cluster Binder Listener--> <gbean class="org.apache.geronimo.tomcat.cluster.ClusterListenerGBean" name="JvmRouteSessionIDBinderListener"> <attribute name="className">org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener</attribute> </gbean> <!-- Cluster Channel Interceptor --> <gbean class="org.apache.geronimo.tomcat.cluster.ChannelInterceptorGBean" name="TomcatChannelInterceptor"> <attribute name="className">org.apache.catalina.tribes.group.interceptors.TcpFailureDetector</attribute> </gbean> </web-app>
where
- web-cluster-server1 should match the WAR file name. It can be different for each node in the cluster.
On each node, deploy your Web application, either via admin console or deploy command, following this syntax:
deploy --user name --password word deploy archive plan
where
- name is replaced with a user name authorized to manage the server. If you omit this option, you will be prompted to enter a user name.
- word is replaced with the password used to authenticate the user. If you omit this option, you will be prompted to enter a password.
- archive is replaced with a file specification to your Web application WAR file.
- plan is replaced with a file specification to your deployment plan.
Note: After server installation, the default user name is initially system, and the default password is manager.
Sample Tomcat clustering with unicast configuration
Static members in a cluster are defined using org.apache.geronimo.tomcat.cluster.StaticMemberGBean
in the deployment plan. You have to specify all static members within the deployment plan to make sure the application is clustered successfully. Refer to the sample code below for an application-scoped unicast clustering configuration on one node. The sample assumes there are only two static members in a cluster environment.
A few notes for better understanding of the sample deployment plan:
- Use
ReceiverGBean
to specify the information of the current node and port number used for communication. - Use
ChannelInterceptorGBeans
to disable the multicast cluster configurations, and specify how the static member are chained together as you can see the configurations ofStaticMember1Interceptor
andStaticMember2Interceptor
. - Use
StaticMemberGBean
to specify the information of the second static member and port number used for communication. - Use
TcpPingInterceptor
to send a ping to another member periodically. You can manage ping interval by setting the interval attibute forTcpPingInterceptor
. It is a good practice to set interval to 240.
To convert this example to a multicast configuration, the DisableMCastInterceptor
, StaticMemberInterceptor
, and StaticMember
definitions should be removed. Also, the value for the address attribute for the ReceiverGBean
definition should be changed to auto.
... <cluster>TomcatCluster</cluster> <gbean name="TomcatCluster" class="org.apache.geronimo.tomcat.cluster.CatalinaClusterGBean"> <attribute name="className">org.apache.catalina.ha.tcp.SimpleTcpCluster</attribute> <attribute name="initParams"/> <reference name="ClusterListenerChain"> <name>TomcatClusterListenerChain</name> </reference> <reference name="TomcatValveChain"> <name>ReplicationValve</name> </reference> <reference name="Channel"> <name>TomcatChannel</name> </reference> <reference name="ClusterManager"> <name>TomcatClusterManager</name> </reference> </gbean> <gbean name="TomcatClusterListenerChain" class="org.apache.geronimo.tomcat.cluster.ClusterListenerGBean"> <attribute name="className">org.apache.catalina.ha.session.ClusterSessionListener</attribute> <attribute name="initParams"/> </gbean> <gbean name="ReplicationValve" class="org.apache.geronimo.tomcat.ValveGBean"> <attribute name="className">org.apache.catalina.ha.tcp.ReplicationValve</attribute> <attribute name="initParams">.*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;</attribute> <reference name="NextValve"> <type>TomcatValve</type> <name>JvmRouteBinderValve</name> </reference> </gbean> <gbean name="JvmRouteBinderValve" class="org.apache.geronimo.tomcat.ValveGBean"> <attribute name="className">org.apache.catalina.ha.session.JvmRouteBinderValve</attribute> <attribute name="initParams">enabled=true</attribute> </gbean> <gbean name="TomcatClusterManager" class="org.apache.geronimo.tomcat.cluster.ClusterManagerGBean"> <attribute name="className">org.apache.catalina.ha.session.DeltaManager</attribute> <attribute name="initParams">name=${clusterName} channelSendOptions=6 expireSessionsOnShutdown=false notifyListenersOnReplication=true mapSendOptions=6 </attribute> </gbean> <gbean name="TomcatChannel" class="org.apache.geronimo.tomcat.cluster.ChannelGBean"> <attribute name="className">org.apache.catalina.tribes.group.GroupChannel</attribute> <attribute name="initParams"/> <reference name="Membership"> <name>ClusterMembership</name> </reference> <reference name="Receiver"> <name>ClusterReceiver</name> </reference> <reference name="Sender"> <name>ClusterSender</name> </reference> <reference name="ChannelInterceptor"> <name>DisableMcastInterceptor</name> </reference> </gbean> <gbean name="ClusterMembership" class="org.apache.geronimo.tomcat.cluster.MembershipServiceGBean"> <attribute name="className">org.apache.catalina.tribes.membership.McastService</attribute> <attribute name="initParams">address=228.0.0.4 port=45564 frequency=500 dropTime=3000 </attribute> </gbean> <gbean name="ClusterReceiver" class="org.apache.geronimo.tomcat.cluster.ReceiverGBean"> <attribute name="className">org.apache.catalina.tribes.transport.nio.NioReceiver</attribute> <attribute name="initParams">address=IPAddress1 port=TCP_port1 selectorTimeout=100 maxThreads=6 </attribute> </gbean> <gbean name="ClusterSender" class="org.apache.geronimo.tomcat.cluster.SenderGBean"> <attribute name="className">org.apache.catalina.tribes.transport.ReplicationTransmitter</attribute> </gbean> <gbean name="DisableMcastInterceptor" class="org.apache.geronimo.tomcat.cluster.ChannelInterceptorGBean"> <attribute name="className">org.apache.geronimo.tomcat.interceptor.DisableMcastInterceptor</attribute> <attribute name="initParams"/> <reference name="NextInterceptor"> <name>TcpPingInterceptor</name> </reference> </gbean> <gbean name="TcpPingInterceptor" class="org.apache.geronimo.tomcat.cluster.ChannelInterceptorGBean"> <attribute name="className">org.apache.catalina.tribes.group.interceptors.TcpPingInterceptor</attribute> <attribute name="initParams">Interval=240</attribute> <reference name="NextInterceptor"> <name>TcpFailureDetector</name> </reference> </gbean> <gbean name="TcpFailureDetector" class="org.apache.geronimo.tomcat.cluster.ChannelInterceptorGBean"> <attribute name="className">org.apache.catalina.tribes.group.interceptors.TcpFailureDetector</attribute> <attribute name="initParams"/> <reference name="NextInterceptor"> <name>StaticMember1Interceptor</name> </reference> </gbean> <gbean name="StaticMember1Interceptor" class="org.apache.geronimo.tomcat.cluster.ChannelInterceptorGBean"> <attribute name="className">org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor</attribute> <attribute name="initParams"/> <reference name="StaticMember"> <name>StaticMember2</name> </reference> <reference name="NextInterceptor"> <name>MessageDispatch15Interceptor</name> </reference> </gbean> <gbean name="MessageDispatch15Interceptor" class="org.apache.geronimo.tomcat.cluster.ChannelInterceptorGBean"> <attribute name="className">org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor</attribute> <attribute name="initParams"/> <reference name="NextInterceptor"> <name>ThroughputInterceptor</name> </reference> </gbean> <gbean name="ThroughputInterceptor" class="org.apache.geronimo.tomcat.cluster.ChannelInterceptorGBean"> <attribute name="className">org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor</attribute> <attribute name="initParams"/> </gbean> <gbean name="StaticMember2" class="org.apache.geronimo.tomcat.cluster.StaticMemberGBean"> <attribute name="className">org.apache.catalina.tribes.membership.StaticMember</attribute> <attribute name="initParams">port=TCP_port2 securePort=-1 host=IPAddress2 domain=test-domain UniqueId={2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} </attribute> </gbean> ...
Where
- IPAddress1 is the IP address or host name of current static member.
- TCP_port1 is the TCP port on the current node to listen for session replication data from other static members.
- IPAddress2 is the IP address or host name of the second static member.
- TCP_port2 is the TCP port on the second static member to listen for session replication data from other static members.
Configuration of unicast clustering with more than two nodes
To set up an application-scoped unicast clustering with more than two nodes, make sure you have defined all the static members in the deployment plan for each server node.
Interceptors can perform actions when a message is sent or received. Use a reference NextInterceptor
in interceptor configurations to chain interceptors together. You can control how the client requests are processed by arranging the order of the interceptor chain. In the following sample code, when the TcpFailureDetector
intercepter catches errors, it calls the next interceptor StaticMember1Interceptor
. The static member referenced inside StaticMember1Interceptor
, static member 2 in this example, will immediately take over the work of the first static member.
... <gbean name="TcpFailureDetector" class="org.apache.geronimo.tomcat.cluster.ChannelInterceptorGBean"> <attribute name="className">org.apache.catalina.tribes.group.interceptors.TcpFailureDetector</attribute> <attribute name="initParams"/> <reference name="NextInterceptor"> <name>StaticMember1Interceptor</name> </reference> </gbean> <gbean name="StaticMember1Interceptor" class="org.apache.geronimo.tomcat.cluster.ChannelInterceptorGBean"> <attribute name="className">org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor</attribute> <attribute name="initParams"/> <reference name="StaticMember"> <name>StaticMember2</name> </reference> <reference name="NextInterceptor"> <name>MessageDispatch15Interceptor</name> </reference> </gbean> ...
All the static members involved should be defined in the deployment plan as well as the relationship between these static members. Use a reference NextStaticMember
in the definition of each static member, except for the last one, to chain static members together. When static member 2 in this example fails to take over the work, static member 3 will immediately take over the work. It is the same for longer static member chain. When a static member fails to take over the work of the previous static member, it calls the next static member in the chain. The request is passed along until a static member can handle the work or it gets to the end.
... <gbean name="StaticMember2" class="org.apache.geronimo.tomcat.cluster.StaticMemberGBean"> <attribute name="className">org.apache.catalina.tribes.membership.StaticMember</attribute> <attribute name="initParams">port=TCP_port2 securePort=-1 host=IPAddress2 domain=test-domain UniqueId={2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} </attribute> <reference name="NextStaticMember"> <name>StaticMember3</name> </reference> </gbean> ...
See the following deployment plan snippet as a complete example of setting up application-scoped unicast clustering with more than two nodes.
... <cluster>TomcatCluster</cluster> <gbean name="TomcatCluster" class="org.apache.geronimo.tomcat.cluster.CatalinaClusterGBean"> <attribute name="className">org.apache.catalina.ha.tcp.SimpleTcpCluster</attribute> <attribute name="initParams">managerClassName=org.apache.catalina.ha.session.DeltaManager expireSessionsOnShutdown=false useDirtyFlag=true notifyListenersOnReplication=true </attribute> <reference name="ClusterListenerChain"> <name>TomcatClusterListenerChain</name> </reference> <reference name="TomcatValveChain"> <name>ReplicationValve</name> </reference> <reference name="Channel"> <name>TomcatChannel</name> </reference> </gbean> <gbean name="TomcatClusterListenerChain" class="org.apache.geronimo.tomcat.cluster.ClusterListenerGBean"> <attribute name="className">org.apache.catalina.ha.session.ClusterSessionListener</attribute> <attribute name="initParams"/> </gbean> <gbean name="ReplicationValve" class="org.apache.geronimo.tomcat.ValveGBean"> <attribute name="className">org.apache.catalina.ha.tcp.ReplicationValve</attribute> <attribute name="initParams">.*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;</attribute> <reference name="NextValve"> <type>TomcatValve</type> <name>JvmRouteBinderValve</name> </reference> </gbean> <gbean name="JvmRouteBinderValve" class="org.apache.geronimo.tomcat.ValveGBean"> <attribute name="className">org.apache.catalina.ha.session.JvmRouteBinderValve</attribute> <attribute name="initParams">enabled=true</attribute> </gbean> <gbean name="TomcatChannel" class="org.apache.geronimo.tomcat.cluster.ChannelGBean"> <attribute name="className">org.apache.catalina.tribes.group.GroupChannel</attribute> <attribute name="initParams"/> <reference name="Membership"> <name>ClusterMembership</name> </reference> <reference name="Receiver"> <name>ClusterReceiver</name> </reference> <reference name="Sender"> <name>ClusterSender</name> </reference> <reference name="ChannelInterceptor"> <name>DisableMcastInterceptor</name> </reference> </gbean> <gbean name="ClusterMembership" class="org.apache.geronimo.tomcat.cluster.MembershipServiceGBean"> <attribute name="className">org.apache.catalina.tribes.membership.McastService</attribute> <attribute name="initParams">address=228.0.0.4 port=45564 frequency=500 dropTime=3000 </attribute> </gbean> <gbean name="ClusterReceiver" class="org.apache.geronimo.tomcat.cluster.ReceiverGBean"> <attribute name="className">org.apache.catalina.tribes.transport.nio.NioReceiver</attribute> <attribute name="initParams">address=IPAddress1 port=TCP_port1 selectorTimeout=100 maxThreads=6 </attribute> </gbean> <gbean name="ClusterSender" class="org.apache.geronimo.tomcat.cluster.SenderGBean"> <attribute name="className">org.apache.catalina.tribes.transport.ReplicationTransmitter</attribute> </gbean> <gbean name="DisableMcastInterceptor" class="org.apache.geronimo.tomcat.cluster.ChannelInterceptorGBean"> <attribute name="className">org.apache.geronimo.tomcat.interceptor.DisableMcastInterceptor</attribute> <attribute name="initParams"/> <reference name="NextInterceptor"> <name>TcpPingInterceptor</name> </reference> </gbean> <gbean name="TcpPingInterceptor" class="org.apache.geronimo.tomcat.cluster.ChannelInterceptorGBean"> <attribute name="className">org.apache.catalina.tribes.group.interceptors.TcpPingInterceptor</attribute> <attribute name="initParams">Interval=240</attribute> <reference name="NextInterceptor"> <name>TcpFailureDetector</name> </reference> </gbean> <gbean name="TcpFailureDetector" class="org.apache.geronimo.tomcat.cluster.ChannelInterceptorGBean"> <attribute name="className">org.apache.catalina.tribes.group.interceptors.TcpFailureDetector</attribute> <attribute name="initParams"/> <reference name="NextInterceptor"> <name>StaticMember1Interceptor</name> </reference> </gbean> <gbean name="StaticMember1Interceptor" class="org.apache.geronimo.tomcat.cluster.ChannelInterceptorGBean"> <attribute name="className">org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor</attribute> <attribute name="initParams"/> <reference name="StaticMember"> <name>StaticMember2</name> </reference> <reference name="NextInterceptor"> <name>MessageDispatch15Interceptor</name> </reference> </gbean> <gbean name="MessageDispatch15Interceptor" class="org.apache.geronimo.tomcat.cluster.ChannelInterceptorGBean"> <attribute name="className">org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor</attribute> <attribute name="initParams"/> <reference name="NextInterceptor"> <name>ThroughputInterceptor</name> </reference> </gbean> <gbean name="ThroughputInterceptor" class="org.apache.geronimo.tomcat.cluster.ChannelInterceptorGBean"> <attribute name="className">org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor</attribute> <attribute name="initParams"/> </gbean> <gbean name="StaticMember2" class="org.apache.geronimo.tomcat.cluster.StaticMemberGBean"> <attribute name="className">org.apache.catalina.tribes.membership.StaticMember</attribute> <attribute name="initParams">port=TCP_port2 securePort=-1 host=IPAddress2 domain=test-domain UniqueId={2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} </attribute> <reference name="NextStaticMember"> <name>StaticMember3</name> </reference> </gbean> <gbean name="StaticMember3" class="org.apache.geronimo.tomcat.cluster.StaticMemberGBean"> <attribute name="className">org.apache.catalina.tribes.membership.StaticMember</attribute> <attribute name="initParams">port=TCP_port3 securePort=-1 host=IPAddress3 domain=test-domain UniqueId={2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} </attribute> </gbean> ...
Where
- IPAddress1 is the IP address or host name of current static member.
- TCP_port1 is the TCP port on the current node to listen for session replication data from other static members.
- IPAddress2 is the IP address or host name of the second static member.
- TCP_port2 is the TCP port on the second static member to listen for session replication data from other static members.
- IPAddress3 is the IP address or host name of the third static member.
- TCP_port3 is the TCP port on the third static member to listen for session replication data from other static members.
Configuring the cluster at Enginee or Host level(Only for G2.2)
You can configure the cluster just like you always did for a standalone Tomcat Web container, input all the clustering configuration into var/catalina/server.xml
file according to your requirement in Geronimo. Both multicast and unicast are supported well. Refer to the following sample codes when you want to configure a Enginee/Host level cluster, make sure these segments are enclosed within <Enginee> or <Host> element in server.xml
. ${clusterName} is from var/config/config-substitutions.properties
, which should be identical within all nodes in a cluster.
Details about each component of the cluster and configuration options can be found in the tomcat documentation at Tomcat6 clustering.
Sample multicast configuration code
... <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8"> <Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true" name="${clusterName}" channelSendOptions="6" mapSendOptions="6"/> <Channel className="org.apache.catalina.tribes.group.GroupChannel"> <Membership className="org.apache.catalina.tribes.membership.McastService" address="228.0.0.4" port="45564" frequency="500" dropTime="3000" /> <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="auto" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6" /> <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender" /> </Sender> <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector" interval="60"/> <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor" /> <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor" /> </Channel> <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;" /> <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve" /> <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener" /> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener" /> </Cluster> ...
Sample unicast configuration code
... <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8"> <Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true" name="${clusterName}" channelSendOptions="6" mapSendOptions="6"/> <Channel className="org.apache.catalina.tribes.group.GroupChannel"> <Membership className="org.apache.catalina.tribes.membership.McastService" address="228.0.0.4" port="45564" frequency="500" dropTime="3000" /> <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="auto" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6" /> <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender" /> </Sender> <Interceptor className="org.apache.geronimo.tomcat.interceptor.DisableMcastInterceptor" /> <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector" interval="60"/> <Interceptor className="org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor"> <Member port="TCP_port" securePort="-1" host="IPAddress" domain="test-domain" UniqueId="{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}" /> </Interceptor> <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor" /> <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor" /> </Channel> <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;" /> <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve" /> <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener" /> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener" /> </Cluster> ...
Where
- IPAddress is the IP address or host name of the second static member.
- TCP_port is the TCP port on the second static member to listen for session replication data from other static members