[66] | 1 | <html><head><META http-equiv="Content-Type" content="text/html; charset=iso-8859-1"><title>Apache Tomcat 6.0 - Clustering/Session Replication HOW-TO</title><meta value="Filip Hanik" name="author"><meta value="fhanik@apache.org" name="email"><meta value="Peter Rossbach" name="author"><meta value="pero@apache.org" name="email"></head><body vlink="#525D76" alink="#525D76" link="#525D76" text="#000000" bgcolor="#ffffff"><table cellspacing="0" width="100%" border="0"><!--PAGE HEADER--><tr><td><!--PROJECT LOGO--><a href="http://tomcat.apache.org/"><img border="0" alt=" |
---|
| 2 | The Apache Tomcat Servlet/JSP Container |
---|
| 3 | " align="right" src="./../images/tomcat.gif"></a></td><td><font face="arial,helvetica,sanserif"><h1>Apache Tomcat 6.0</h1></font></td><td><!--APACHE LOGO--><a href="http://www.apache.org/"><img border="0" alt="Apache Logo" align="right" src="./../images/asf-logo.gif"></a></td></tr></table><table cellspacing="4" width="100%" border="0"><!--HEADER SEPARATOR--><tr><td colspan="2"><hr size="1" noshade></td></tr><tr><!--RIGHT SIDE MAIN BODY--><td align="left" valign="top" width="80%"><table cellspacing="4" width="100%" border="0"><tr><td valign="top" align="left"><h1>Apache Tomcat 6.0</h1><h2>Clustering/Session Replication HOW-TO</h2></td><td nowrap="true" valign="top" align="right"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table><table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#525D76"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Important Note"><strong>Important Note</strong></a></font></td></tr><tr><td><blockquote> |
---|
| 4 | <p><b>You can also check the <a href="../config/cluster.html">configuration reference documentation.</a></b> |
---|
| 5 | </p> |
---|
| 6 | </blockquote></td></tr></table><table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#525D76"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="For the impatient"><strong>For the impatient</strong></a></font></td></tr><tr><td><blockquote> |
---|
| 7 | <p> |
---|
| 8 | Simply add <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre><Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/></pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> |
---|
| 9 | to your <code><Engine></code> or your <code><Host></code> element to enable clustering. |
---|
| 10 | </p> |
---|
| 11 | <p> |
---|
| 12 | Using the above configuration will enable all-to-all session replication |
---|
| 13 | using the <code>DeltaManager</code> to replicate session deltas. By all-to-all we mean that the session gets replicated to all the other |
---|
| 14 | nodes in the cluster. This works great for smaller cluster but we don't recommend it for larger clusters(a lot of tomcat nodes). |
---|
| 15 | Also when using the delta manager it will replicate to all nodes, even nodes that don't have the application deployed.<br> |
---|
| 16 | To get around this problem, you'll want to use the BackupManager. This manager only replicates the session data to one backup |
---|
| 17 | node, and only to nodes that have the application deployed. Downside of the BackupManager: not quite as battle tested as the delta manager. |
---|
| 18 | <br> |
---|
| 19 | Here are some of the important default values:<br> |
---|
| 20 | 1. Multicast address is 228.0.0.4<br> |
---|
| 21 | 2. Multicast port is 45564 (the port and the address together determine cluster membership.<br> |
---|
| 22 | 3. The IP broadcasted is <code>java.net.InetAddress.getLocalHost().getHostAddress()</code> (make sure you don't broadcast 127.0.0.1, this is a common error)<br> |
---|
| 23 | 4. The TCP port listening for replication messages is the first available server socket in range <code>4000-4100</code><br> |
---|
| 24 | 5. Two listeners are configured <code>ClusterSessionListener</code> and <code>JvmRouteSessionIDBinderListener</code><br> |
---|
| 25 | 6. Two interceptors are configured <code>TcpFailureDetector</code> and <code>MessageDispatch15Interceptor</code><br> |
---|
| 26 | The following is the default cluster configuration:<br> |
---|
| 27 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> |
---|
| 28 | <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" |
---|
| 29 | channelSendOptions="8"> |
---|
| 30 | |
---|
| 31 | <Manager className="org.apache.catalina.ha.session.DeltaManager" |
---|
| 32 | expireSessionsOnShutdown="false" |
---|
| 33 | notifyListenersOnReplication="true"/> |
---|
| 34 | |
---|
| 35 | <Channel className="org.apache.catalina.tribes.group.GroupChannel"> |
---|
| 36 | <Membership className="org.apache.catalina.tribes.membership.McastService" |
---|
| 37 | address="228.0.0.4" |
---|
| 38 | port="45564" |
---|
| 39 | frequency="500" |
---|
| 40 | dropTime="3000"/> |
---|
| 41 | <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" |
---|
| 42 | address="auto" |
---|
| 43 | port="4000" |
---|
| 44 | autoBind="100" |
---|
| 45 | selectorTimeout="5000" |
---|
| 46 | maxThreads="6"/> |
---|
| 47 | |
---|
| 48 | <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> |
---|
| 49 | <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> |
---|
| 50 | </Sender> |
---|
| 51 | <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/> |
---|
| 52 | <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/> |
---|
| 53 | </Channel> |
---|
| 54 | |
---|
| 55 | <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" |
---|
| 56 | filter=""/> |
---|
| 57 | <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/> |
---|
| 58 | |
---|
| 59 | <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" |
---|
| 60 | tempDir="/tmp/war-temp/" |
---|
| 61 | deployDir="/tmp/war-deploy/" |
---|
| 62 | watchDir="/tmp/war-listen/" |
---|
| 63 | watchEnabled="false"/> |
---|
| 64 | |
---|
| 65 | <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/> |
---|
| 66 | <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> |
---|
| 67 | </Cluster> |
---|
| 68 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> |
---|
| 69 | </p> |
---|
| 70 | <p>Will cover this section in more detail later in this document.</p> |
---|
| 71 | </blockquote></td></tr></table><table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#525D76"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Cluster Basics"><strong>Cluster Basics</strong></a></font></td></tr><tr><td><blockquote> |
---|
| 72 | |
---|
| 73 | <p>To run session replication in your Tomcat 6.0 container, the following steps |
---|
| 74 | should be completed:</p> |
---|
| 75 | <ul> |
---|
| 76 | <li>All your session attributes must implement <code>java.io.Serializable</code></li> |
---|
| 77 | <li>Uncomment the <code>Cluster</code> element in server.xml</li> |
---|
| 78 | <li>If you have defined custom cluster valves, make sure you have the <code>ReplicationValve</code> defined as well under the Cluster element in server.xml</li> |
---|
| 79 | <li>If your Tomcat instances are running on the same machine, make sure the <code>tcpListenPort</code> |
---|
| 80 | attribute is unique for each instance, in most cases Tomcat is smart enough to resolve this on it's own by autodetecting available ports in the range 4000-4100</li> |
---|
| 81 | <li>Make sure your <code>web.xml</code> has the <code><distributable/></code> element |
---|
| 82 | or set at your <code><Context distributable="true" /></code></li> |
---|
| 83 | <li>If you are using mod_jk, make sure that jvmRoute attribute is set at your Engine <code><Engine name="Catalina" jvmRoute="node01" ></code> |
---|
| 84 | and that the jvmRoute attribute value matches your worker name in workers.properties</li> |
---|
| 85 | <li>Make sure that all nodes have the same time and sync with NTP service!</li> |
---|
| 86 | <li>Make sure that your loadbalancer is configured for sticky session mode.</li> |
---|
| 87 | </ul> |
---|
| 88 | <p>Load balancing can be achieved through many techniques, as seen in the |
---|
| 89 | <a href="balancer-howto.html">Load Balancing</a> chapter.</p> |
---|
| 90 | <p>Note: Remember that your session state is tracked by a cookie, so your URL must look the same from the out |
---|
| 91 | side otherwise, a new session will be created.</p> |
---|
| 92 | <p>Note: Clustering support currently requires the JDK version 1.5 or later.</p> |
---|
| 93 | <p>The Cluster module uses the Tomcat JULI logging framework, so you can configure logging |
---|
| 94 | through the regular logging.properties file. To track messages, you can enable logging on the key:<code>org.apache.catalina.tribes.MESSAGES</code></p> |
---|
| 95 | </blockquote></td></tr></table><table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#525D76"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Overview"><strong>Overview</strong></a></font></td></tr><tr><td><blockquote> |
---|
| 96 | |
---|
| 97 | <p>To enable session replication in Tomcat, three different paths can be followed to achieve the exact same thing:</p> |
---|
| 98 | <ol> |
---|
| 99 | <li>Using session persistence, and saving the session to a shared file system (PersistenceManager + FileStore)</li> |
---|
| 100 | <li>Using session persistence, and saving the session to a shared database (PersistenceManager + JDBCStore)</li> |
---|
| 101 | <li>Using in-memory-replication, using the SimpleTcpCluster that ships with Tomcat 6 (lib/catalina-tribes.jar + lib/catalina-ha.jar)</li> |
---|
| 102 | </ol> |
---|
| 103 | |
---|
| 104 | <p>In this release of session replication, Tomcat can perform an all-to-all replication of session state using the <code>DeltaManager</code> or |
---|
| 105 | perform backup replication to only one node using the <code>BackupManager</code>. |
---|
| 106 | The all-to-all replication is an algorithm that is only efficient when the clusters are small. For larger clusters, to use |
---|
| 107 | a primary-secondary session replication where the session will only be stored at one backup server simply setup the BackupManager. <br> |
---|
| 108 | Currently you can use the domain worker attribute (mod_jk > 1.2.8) to build cluster partitions |
---|
| 109 | with the potential of having a more scaleable cluster solution with the DeltaManager(you'll need to configure the domain interceptor for this). |
---|
| 110 | In order to keep the network traffic down in an all-to-all environment, you can split your cluster |
---|
| 111 | into smaller groups. This can be easily achieved by using different multicast addresses for the different groups. |
---|
| 112 | A very simple setup would look like this: |
---|
| 113 | </p> |
---|
| 114 | |
---|
| 115 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> |
---|
| 116 | DNS Round Robin |
---|
| 117 | | |
---|
| 118 | Load Balancer |
---|
| 119 | / \ |
---|
| 120 | Cluster1 Cluster2 |
---|
| 121 | / \ / \ |
---|
| 122 | Tomcat1 Tomcat2 Tomcat3 Tomcat4 |
---|
| 123 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> |
---|
| 124 | |
---|
| 125 | <p>What is important to mention here, is that session replication is only the beginning of clustering. |
---|
| 126 | Another popular concept used to implement clusters is farming, ie, you deploy your apps only to one |
---|
| 127 | server, and the cluster will distribute the deployments across the entire cluster. |
---|
| 128 | This is all capabilities that can go into with the FarmWarDeployer (s. cluster example at <code>server.xml</code>)</p> |
---|
| 129 | <p>In the next section will go deeper into how session replication works and how to configure it.</p> |
---|
| 130 | |
---|
| 131 | </blockquote></td></tr></table><table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#525D76"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Cluster Information"><strong>Cluster Information</strong></a></font></td></tr><tr><td><blockquote> |
---|
| 132 | <p>Membership is established using multicast heartbeats. |
---|
| 133 | Hence, if you wish to subdivide your clusters, you can do this by |
---|
| 134 | changing the multicast IP address or port in the <code><Membership></code> element. |
---|
| 135 | </p> |
---|
| 136 | <p> |
---|
| 137 | The heartbeat contains the IP address of the Tomcat node and the TCP port that |
---|
| 138 | Tomcat listens to for replication traffic. All data communication happens over TCP. |
---|
| 139 | </p> |
---|
| 140 | <p> |
---|
| 141 | The <code>ReplicationValve</code> is used to find out when the request has been completed and initiate the |
---|
| 142 | replication, if any. Data is only replicated if the session has changed (by calling setAttribute or removeAttribute |
---|
| 143 | on the session). |
---|
| 144 | </p> |
---|
| 145 | <p> |
---|
| 146 | One of the most important performance considerations is the synchronous versus asynchronous replication. |
---|
| 147 | In a synchronous replication mode the request doesn't return until the replicated session has been |
---|
| 148 | sent over the wire and reinstantiated on all the other cluster nodes. |
---|
| 149 | Synchronous vs asynchronous is configured using the <code>channelSendOptions</code> |
---|
| 150 | flag and is an integer value. The default value for the <code>SimpleTcpCluster/DeltaManager</code> combo is |
---|
| 151 | 8, which is asynchronous. You can read more on the <a href="../tribes/introduction.html">send flag(overview)</a> or the |
---|
| 152 | <a href="http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/tribes/Channel.html">send flag(javadoc)</a>. |
---|
| 153 | During async replication, the request is returned before the data has been replicated. async replication yields shorter |
---|
| 154 | request times, and synchronous replication guarantees the session to be replicated before the request returns. |
---|
| 155 | </p> |
---|
| 156 | </blockquote></td></tr></table><table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#525D76"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Bind session after crash to failover node"><strong>Bind session after crash to failover node</strong></a></font></td></tr><tr><td><blockquote> |
---|
| 157 | <p> |
---|
| 158 | If you are using mod_jk and not using sticky sessions or for some reasons sticky session don't |
---|
| 159 | work, or you are simply failing over, the session id will need to be modified as it previously contained |
---|
| 160 | the worker id of the previous tomcat (as defined by jvmRoute in the Engine element). |
---|
| 161 | To solve this, we will use the JvmRouteBinderValve. |
---|
| 162 | </p> |
---|
| 163 | <p> |
---|
| 164 | The JvmRouteBinderValve rewrites the session id to ensure that the next request will remain sticky |
---|
| 165 | (and not fall back to go to random nodes since the worker is no longer available) after a fail over. |
---|
| 166 | The valve rewrites the JSESSIONID value in the cookie with the same name. |
---|
| 167 | Not having this valve in place, will make it harder to ensure stickyness in case of a failure for the mod_jk module. |
---|
| 168 | </p> |
---|
| 169 | <p> |
---|
| 170 | By default, if no valves are configured, the JvmRouteBinderValve is added on. |
---|
| 171 | The cluster message listener called JvmRouteSessionIDBinderListener is also defined by default and is used to actually rewrite the |
---|
| 172 | session id on the other nodes in the cluster once a fail over has occurred. |
---|
| 173 | Remember, if you are adding your own valves or cluster listeners in server.xml then the defaults are no longer valid, |
---|
| 174 | make sure that you add in all the appropriate valves and listeners as defined by the default. |
---|
| 175 | </p> |
---|
| 176 | <p> |
---|
| 177 | <b>Hint:</b><br> |
---|
| 178 | With attribute <i>sessionIdAttribute</i> you can change the request attribute name that included the old session id. |
---|
| 179 | Default attribuite name is <i>org.apache.catalina.cluster.session.JvmRouteOrignalSessionID</i>. |
---|
| 180 | </p> |
---|
| 181 | <p> |
---|
| 182 | <b>Trick:</b><br> |
---|
| 183 | You can enable this mod_jk turnover mode via JMX before you drop a node to all backup nodes! |
---|
| 184 | Set enable true on all JvmRouteBinderValve backups, disable worker at mod_jk |
---|
| 185 | and then drop node and restart it! Then enable mod_jk Worker and disable JvmRouteBinderValves again. |
---|
| 186 | This use case means that only requested session are migrated. |
---|
| 187 | </p> |
---|
| 188 | |
---|
| 189 | |
---|
| 190 | |
---|
| 191 | </blockquote></td></tr></table><table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#525D76"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Configuration Example"><strong>Configuration Example</strong></a></font></td></tr><tr><td><blockquote> |
---|
| 192 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> |
---|
| 193 | <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" |
---|
| 194 | channelSendOptions="6"> |
---|
| 195 | |
---|
| 196 | <Manager className="org.apache.catalina.ha.session.BackupManager" |
---|
| 197 | expireSessionsOnShutdown="false" |
---|
| 198 | notifyListenersOnReplication="true" |
---|
| 199 | mapSendOptions="6"/> |
---|
| 200 | <!-- |
---|
| 201 | <Manager className="org.apache.catalina.ha.session.DeltaManager" |
---|
| 202 | expireSessionsOnShutdown="false" |
---|
| 203 | notifyListenersOnReplication="true"/> |
---|
| 204 | --> |
---|
| 205 | <Channel className="org.apache.catalina.tribes.group.GroupChannel"> |
---|
| 206 | <Membership className="org.apache.catalina.tribes.membership.McastService" |
---|
| 207 | address="228.0.0.4" |
---|
| 208 | port="45564" |
---|
| 209 | frequency="500" |
---|
| 210 | dropTime="3000"/> |
---|
| 211 | <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" |
---|
| 212 | address="auto" |
---|
| 213 | port="5000" |
---|
| 214 | selectorTimeout="100" |
---|
| 215 | maxThreads="6"/> |
---|
| 216 | |
---|
| 217 | <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> |
---|
| 218 | <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> |
---|
| 219 | </Sender> |
---|
| 220 | <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/> |
---|
| 221 | <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/> |
---|
| 222 | <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/> |
---|
| 223 | </Channel> |
---|
| 224 | |
---|
| 225 | <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" |
---|
| 226 | filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/> |
---|
| 227 | |
---|
| 228 | <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" |
---|
| 229 | tempDir="/tmp/war-temp/" |
---|
| 230 | deployDir="/tmp/war-deploy/" |
---|
| 231 | watchDir="/tmp/war-listen/" |
---|
| 232 | watchEnabled="false"/> |
---|
| 233 | |
---|
| 234 | <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> |
---|
| 235 | </Cluster> |
---|
| 236 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> |
---|
| 237 | <p> |
---|
| 238 | Break it down!! |
---|
| 239 | </p> |
---|
| 240 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> |
---|
| 241 | <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" |
---|
| 242 | channelSendOptions="6"> |
---|
| 243 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> |
---|
| 244 | <p> |
---|
| 245 | The main element, inside this element all cluster details can be configured. |
---|
| 246 | The <code>channelSendOptions</code> is the flag that is attached to each message sent by the |
---|
| 247 | SimpleTcpCluster class or any objects that are invoking the SimpleTcpCluster.send method. |
---|
| 248 | The description of the send flags is available at <a href="http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/tribes/Channel.html"> |
---|
| 249 | our javadoc site</a> |
---|
| 250 | The <code>DeltaManager</code> sends information using the SimpleTcpCluster.send method, while the backup manager |
---|
| 251 | sends it itself directly through the channel. |
---|
| 252 | <br>For more info, Please visit the <a href="../config/cluster.html">reference documentation</a> |
---|
| 253 | </p> |
---|
| 254 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> |
---|
| 255 | <Manager className="org.apache.catalina.ha.session.BackupManager" |
---|
| 256 | expireSessionsOnShutdown="false" |
---|
| 257 | notifyListenersOnReplication="true" |
---|
| 258 | mapSendOptions="6"/> |
---|
| 259 | <!-- |
---|
| 260 | <Manager className="org.apache.catalina.ha.session.DeltaManager" |
---|
| 261 | expireSessionsOnShutdown="false" |
---|
| 262 | notifyListenersOnReplication="true"/> |
---|
| 263 | --> |
---|
| 264 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> |
---|
| 265 | <p> |
---|
| 266 | This is a template for the manager configuration that will be used if no manager is defined in the <Context> |
---|
| 267 | element. In Tomcat 5.x each webapp marked distributable had to use the same manager, this is no longer the case |
---|
| 268 | since Tomcat 6 you can define a manager class for each webapp, so that you can mix managers in your cluster. |
---|
| 269 | Obviously the managers on one node's application has to correspond with the same manager on the same application on the other node. |
---|
| 270 | If no manager has been specified for the webapp, and the webapp is marked <distributable/> Tomcat will take this manager configuration |
---|
| 271 | and create a manager instance cloning this configuration. |
---|
| 272 | <br>For more info, Please visit the <a href="../config/cluster-manager.html">reference documentation</a> |
---|
| 273 | </p> |
---|
| 274 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> |
---|
| 275 | <Channel className="org.apache.catalina.tribes.group.GroupChannel"> |
---|
| 276 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> |
---|
| 277 | <p> |
---|
| 278 | The channel element is <a href="../tribes/introduction.html">Tribes</a>, the group communication framework |
---|
| 279 | used inside Tomcat. This element encapsulates everything that has to do with communication and membership logic. |
---|
| 280 | <br>For more info, Please visit the <a href="../config/cluster-channel.html">reference documentation</a> |
---|
| 281 | </p> |
---|
| 282 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> |
---|
| 283 | <Membership className="org.apache.catalina.tribes.membership.McastService" |
---|
| 284 | address="228.0.0.4" |
---|
| 285 | port="45564" |
---|
| 286 | frequency="500" |
---|
| 287 | dropTime="3000"/> |
---|
| 288 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> |
---|
| 289 | <p> |
---|
| 290 | Membership is done using multicasting. Please note that Tribes also supports static memberships using the |
---|
| 291 | <code>StaticMembershipInterceptor</code> if you want to extend your membership to points beyond multicasting. |
---|
| 292 | The address attribute is the multicast address used and the port is the multicast port. These two together |
---|
| 293 | create the cluster separation. If you want a QA cluster and a production cluster, the easiest config is to |
---|
| 294 | have the QA cluster be on a separate multicast address/port combination the the production cluster.<br> |
---|
| 295 | The membership component broadcasts TCP adress/port of itselt to the other nodes so that communication between |
---|
| 296 | nodes can be done over TCP. Please note that the address being broadcasted is the one of the |
---|
| 297 | <code>Receiver.address</code> attribute. |
---|
| 298 | <br>For more info, Please visit the <a href="../config/cluster-membership.html">reference documentation</a> |
---|
| 299 | </p> |
---|
| 300 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> |
---|
| 301 | <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" |
---|
| 302 | address="auto" |
---|
| 303 | port="5000" |
---|
| 304 | selectorTimeout="100" |
---|
| 305 | maxThreads="6"/> |
---|
| 306 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> |
---|
| 307 | <p> |
---|
| 308 | In tribes the logic of sending and receiving data has been broken into two functional components. The Receiver, as the name suggests |
---|
| 309 | is responsible for receiving messages. Since the Tribes stack is thread less, (a popular improvement now adopted by other frameworks as well), |
---|
| 310 | there is a thread pool in this component that has a maxThreads and minThreads setting.<br> |
---|
| 311 | The address attribute is the host address that will be broadcasted by the membership component to the other nodes. |
---|
| 312 | <br>For more info, Please visit the <a href="../config/cluster-receiver.html">reference documentation</a> |
---|
| 313 | </p> |
---|
| 314 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> |
---|
| 315 | |
---|
| 316 | <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> |
---|
| 317 | <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> |
---|
| 318 | </Sender> |
---|
| 319 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> |
---|
| 320 | <p> |
---|
| 321 | The sender component, as the name indicates is responsible for sending messages to other nodes. |
---|
| 322 | The sender has a shell component, the <code>ReplicationTransmitter</code> but the real stuff done is done in the |
---|
| 323 | sub component, <code>Transport</code>. |
---|
| 324 | Tribes support having a pool of senders, so that messages can be sent in parallel and if using the NIO sender, |
---|
| 325 | you can send messages concurrently as well.<br> |
---|
| 326 | Concurrently means one message to multiple senders at the same time and Parallel means multiple messages to multiple senders |
---|
| 327 | at the same time. |
---|
| 328 | <br>For more info, Please visit the <a href="../config/cluster-sender.html">reference documentation</a> |
---|
| 329 | </p> |
---|
| 330 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> |
---|
| 331 | <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/> |
---|
| 332 | <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/> |
---|
| 333 | <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/> |
---|
| 334 | </Channel> |
---|
| 335 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> |
---|
| 336 | <p> |
---|
| 337 | Tribes uses a stack to send messages through. Each element in the stack is called an interceptor, and works much like the valves do |
---|
| 338 | in the Tomcat servlet container. |
---|
| 339 | Using interceptors, logic can be broken into more managable pieces of code. The interceptors configured above are:<br> |
---|
| 340 | TcpFailureDetector - verifies crashed members through TCP, if multicast packets get dropped, this interceptor protects against false positives, |
---|
| 341 | ie the node marked as crashed even though it still is alive and running.<br> |
---|
| 342 | MessageDispatch15Interceptor - dispatches messages to a thread (thread pool) to send message asynchrously.<br> |
---|
| 343 | ThroughputInterceptor - prints out simple stats on message traffic.<br> |
---|
| 344 | Please note that the order of interceptors is important. the way they are defined in server.xml is the way they are represented in the |
---|
| 345 | channel stack. Think of it as a linked list, with the head being the first most interceptor and the tail the last. |
---|
| 346 | <br>For more info, Please visit the <a href="../config/cluster-interceptor.html">reference documentation</a> |
---|
| 347 | </p> |
---|
| 348 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> |
---|
| 349 | <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" |
---|
| 350 | filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/> |
---|
| 351 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> |
---|
| 352 | <p> |
---|
| 353 | The cluster uses valves to track requests to web applications, we've mentioned the ReplicationValve and the JvmRouteBinderValve above. |
---|
| 354 | The <Cluster> element itself is not part of the pipeline in Tomcat, instead the cluster adds the valve to its parent container. |
---|
| 355 | If the <Cluster> elements is configured in the <Engine> element, the valves get added to the engine and so on. |
---|
| 356 | <br>For more info, Please visit the <a href="../config/cluster-valve.html">reference documentation</a> |
---|
| 357 | </p> |
---|
| 358 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> |
---|
| 359 | <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" |
---|
| 360 | tempDir="/tmp/war-temp/" |
---|
| 361 | deployDir="/tmp/war-deploy/" |
---|
| 362 | watchDir="/tmp/war-listen/" |
---|
| 363 | watchEnabled="false"/> |
---|
| 364 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> |
---|
| 365 | <p> |
---|
| 366 | The default tomcat cluster supports farmed deployment, ie, the cluster can deploy and undeploy applications on the other nodes. |
---|
| 367 | The state of this component is currently in flux but will be addressed soon. There was a change in the deployment algorithm |
---|
| 368 | between Tomcat 5.0 and 5.5 and at that point, the logic of this component changed to where the deploy dir has to match the |
---|
| 369 | webapps directory. |
---|
| 370 | <br>For more info, Please visit the <a href="../config/cluster-deployer.html">reference documentation</a> |
---|
| 371 | </p> |
---|
| 372 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> |
---|
| 373 | <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> |
---|
| 374 | </Cluster> |
---|
| 375 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> |
---|
| 376 | <p> |
---|
| 377 | Since the SimpleTcpCluster itself is a sender and receiver of the Channel object, components can register themselves as listeners to |
---|
| 378 | the SimpleTcpCluster. The listener above <code>ClusterSessionListener</code> listens for DeltaManager replication messages |
---|
| 379 | and applies the deltas to the manager that in turn applies it to the session. |
---|
| 380 | <br>For more info, Please visit the <a href="../config/cluster-listener.html">reference documentation</a> |
---|
| 381 | </p> |
---|
| 382 | |
---|
| 383 | </blockquote></td></tr></table><table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#525D76"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Cluster Architecture"><strong>Cluster Architecture</strong></a></font></td></tr><tr><td><blockquote> |
---|
| 384 | |
---|
| 385 | <p><b>Component Levels:</b> |
---|
| 386 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> |
---|
| 387 | Server |
---|
| 388 | | |
---|
| 389 | Service |
---|
| 390 | | |
---|
| 391 | Engine |
---|
| 392 | | \ |
---|
| 393 | | --- Cluster --* |
---|
| 394 | | |
---|
| 395 | Host |
---|
| 396 | | |
---|
| 397 | ------ |
---|
| 398 | / \ |
---|
| 399 | Cluster Context(1-N) |
---|
| 400 | | \ |
---|
| 401 | | -- Manager |
---|
| 402 | | \ |
---|
| 403 | | -- DeltaManager |
---|
| 404 | | -- BackupManager |
---|
| 405 | | |
---|
| 406 | --------------------------- |
---|
| 407 | | \ |
---|
| 408 | Channel \ |
---|
| 409 | ----------------------------- \ |
---|
| 410 | | \ |
---|
| 411 | Interceptor_1 .. \ |
---|
| 412 | | \ |
---|
| 413 | Interceptor_N \ |
---|
| 414 | ----------------------------- \ |
---|
| 415 | | | | \ |
---|
| 416 | Receiver Sender Membership \ |
---|
| 417 | -- Valve |
---|
| 418 | | \ |
---|
| 419 | | -- ReplicationValve |
---|
| 420 | | -- JvmRouteBinderValve |
---|
| 421 | | |
---|
| 422 | -- LifecycleListener |
---|
| 423 | | |
---|
| 424 | -- ClusterListener |
---|
| 425 | | \ |
---|
| 426 | | -- ClusterSessionListener |
---|
| 427 | | -- JvmRouteSessionIDBinderListener |
---|
| 428 | | |
---|
| 429 | -- Deployer |
---|
| 430 | \ |
---|
| 431 | -- FarmWarDeployer |
---|
| 432 | |
---|
| 433 | |
---|
| 434 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> |
---|
| 435 | </p> |
---|
| 436 | |
---|
| 437 | </blockquote></td></tr></table><table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#525D76"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="How it Works"><strong>How it Works</strong></a></font></td></tr><tr><td><blockquote> |
---|
| 438 | <p>To make it easy to understand how clustering works, We are gonna take you through a series of scenarios. |
---|
| 439 | In the scenario we only plan to use two tomcat instances <code>TomcatA</code> and <code>TomcatB</code>. |
---|
| 440 | We will cover the following sequence of events:</p> |
---|
| 441 | |
---|
| 442 | <ol> |
---|
| 443 | <li><code>TomcatA</code> starts up</li> |
---|
| 444 | <li><code>TomcatB</code> starts up (Wait that TomcatA start is complete)</li> |
---|
| 445 | <li><code>TomcatA</code> receives a request, a session <code>S1</code> is created.</li> |
---|
| 446 | <li><code>TomcatA</code> crashes</li> |
---|
| 447 | <li><code>TomcatB</code> receives a request for session <code>S1</code></li> |
---|
| 448 | <li><code>TomcatA</code> starts up</li> |
---|
| 449 | <li><code>TomcatA</code> receives a request, invalidate is called on the session (<code>S1</code>)</li> |
---|
| 450 | <li><code>TomcatB</code> receives a request, for a new session (<code>S2</code>)</li> |
---|
| 451 | <li><code>TomcatA</code> The session <code>S2</code> expires due to inactivity.</li> |
---|
| 452 | </ol> |
---|
| 453 | |
---|
| 454 | <p>Ok, now that we have a good sequence, we will take you through exactly what happens in the session repliction code</p> |
---|
| 455 | |
---|
| 456 | <ol> |
---|
| 457 | <li><b><code>TomcatA</code> starts up</b> |
---|
| 458 | <p> |
---|
| 459 | Tomcat starts up using the standard start up sequence. When the Host object is created, a cluster object is associated with it. |
---|
| 460 | When the contexts are parsed, if the distributable element is in place in web.xml |
---|
| 461 | Tomcat asks the Cluster class (in this case <code>SimpleTcpCluster</code>) to create a manager |
---|
| 462 | for the replicated context. So with clustering enabled, distributable set in web.xml |
---|
| 463 | Tomcat will create a <code>DeltaManager</code> for that context instead of a <code>StandardManager</code>. |
---|
| 464 | The cluster class will start up a membership service (multicast) and a replication service (tcp unicast). |
---|
| 465 | More on the architecture further down in this document. |
---|
| 466 | </p><p></p> |
---|
| 467 | </li> |
---|
| 468 | <li><b><code>TomcatB</code> starts up</b> |
---|
| 469 | <p> |
---|
| 470 | When TomcatB starts up, it follows the same sequence as TomcatA did with one exception. |
---|
| 471 | The cluster is started and will establish a membership (TomcatA,TomcatB). |
---|
| 472 | TomcatB will now request the session state from a server that already exists in the cluster, |
---|
| 473 | in this case TomcatA. TomcatA responds to the request, and before TomcatB starts listening |
---|
| 474 | for HTTP requests, the state has been transferred from TomcatA to TomcatB. |
---|
| 475 | In case TomcatA doesn't respond, TomcatB will time out after 60 seconds, and issue a log |
---|
| 476 | entry. The session state gets transferred for each web application that has distributable in |
---|
| 477 | its web.xml. Note: To use session replication efficiently, all your tomcat instances should be |
---|
| 478 | configured the same. |
---|
| 479 | </p><p></p> |
---|
| 480 | </li> |
---|
| 481 | <li><B><code>TomcatA</code> receives a request, a session <code>S1</code> is created.</B> |
---|
| 482 | <p> |
---|
| 483 | The request coming in to TomcatA is treated exactly the same way as without session replication. |
---|
| 484 | The action happens when the request is completed, the <code>ReplicationValve</code> will intercept |
---|
| 485 | the request before the response is returned to the user. |
---|
| 486 | At this point it finds that the session has been modified, and it uses TCP to replicata the |
---|
| 487 | session to TomcatB. Once the serialized data has been handed off to the operating systems TCP logic, |
---|
| 488 | the request returns to the user, back through the valve pipeline. |
---|
| 489 | For each request the entire session is replicated, this allows code that modifies attributes |
---|
| 490 | in the session without calling setAttribute or removeAttribute to be replicated. |
---|
| 491 | a useDirtyFlag configuration parameter can be used to optimize the number of times |
---|
| 492 | a session is replicated. |
---|
| 493 | </p><p></p> |
---|
| 494 | |
---|
| 495 | </li> |
---|
| 496 | <li><b><code>TomcatA</code> crashes</b> |
---|
| 497 | <p> |
---|
| 498 | When TomcatA crashes, TomcatB receives a notification that TomcatA has dropped out |
---|
| 499 | of the cluster. TomcatB removes TomcatA from its membership list, and TomcatA will no longer |
---|
| 500 | be notified of any changes that occurs in TomcatB. |
---|
| 501 | The load balancer will redirect the requests from TomcatA to TomcatB and all the sessions |
---|
| 502 | are current. |
---|
| 503 | </p><p></p> |
---|
| 504 | </li> |
---|
| 505 | <li><b><code>TomcatB</code> receives a request for session <code>S1</code></b> |
---|
| 506 | <p>Nothing exciting, TomcatB will process the request as any other request. |
---|
| 507 | </p><p></p> |
---|
| 508 | </li> |
---|
| 509 | <li><b><code>TomcatA</code> starts up</b> |
---|
| 510 | <p>Upon start up, before TomcatA starts taking new request and making itself |
---|
| 511 | available to it will follow the start up sequence described above 1) 2). |
---|
| 512 | It will join the cluster, contact TomcatB for the current state of all the sessions. |
---|
| 513 | And once it receives the session state, it finishes loading and opens its HTTP/mod_jk ports. |
---|
| 514 | So no requests will make it to TomcatA until it has received the session state from TomcatB. |
---|
| 515 | </p><p></p> |
---|
| 516 | </li> |
---|
| 517 | <li><b><code>TomcatA</code> receives a request, invalidate is called on the session (<code>S1</code>)</b> |
---|
| 518 | <p>The invalidate is call is intercepted, and the session is queued with invalidated sessions. |
---|
| 519 | When the request is complete, instead of sending out the session that has changed, it sends out |
---|
| 520 | an "expire" message to TomcatB and TomcatB will invalidate the session as well. |
---|
| 521 | </p><p></p> |
---|
| 522 | |
---|
| 523 | </li> |
---|
| 524 | <li><b><code>TomcatB</code> receives a request, for a new session (<code>S2</code>)</b> |
---|
| 525 | <p>Same scenario as in step 3) |
---|
| 526 | </p><p></p> |
---|
| 527 | |
---|
| 528 | |
---|
| 529 | </li> |
---|
| 530 | <li><code>TomcatA</code> The session <code>S2</code> expires due to inactivity. |
---|
| 531 | <p>The invalidate is call is intercepted the same was as when a session is invalidated by the user, |
---|
| 532 | and the session is queued with invalidated sessions. |
---|
| 533 | At this point, the invalidet session will not be replicated across until |
---|
| 534 | another request comes through the system and checks the invalid queue. |
---|
| 535 | </p><p></p> |
---|
| 536 | </li> |
---|
| 537 | </ol> |
---|
| 538 | |
---|
| 539 | <p>Phuuuhh! :)</p> |
---|
| 540 | |
---|
| 541 | <p><b>Membership</b> |
---|
| 542 | Clustering membership is established using very simple multicast pings. |
---|
| 543 | Each Tomcat instance will periodically send out a multicast ping, |
---|
| 544 | in the ping message the instance will broad cast its IP and TCP listen port |
---|
| 545 | for replication. |
---|
| 546 | If an instance has not received such a ping within a given timeframe, the |
---|
| 547 | member is considered dead. Very simple, and very effective! |
---|
| 548 | Of course, you need to enable multicasting on your system. |
---|
| 549 | </p> |
---|
| 550 | |
---|
| 551 | <p><b>TCP Replication</b> |
---|
| 552 | Once a multicast ping has been received, the member is added to the cluster |
---|
| 553 | Upon the next replication request, the sending instance will use the host and |
---|
| 554 | port info and establish a TCP socket. Using this socket it sends over the serialized data. |
---|
| 555 | The reason I choose TCP sockets is because it has built in flow control and guaranteed delivery. |
---|
| 556 | So I know, when I send some data, it will make it there :) |
---|
| 557 | </p> |
---|
| 558 | |
---|
| 559 | <p><b>Distributed locking and pages using frames</b> |
---|
| 560 | Tomcat does not keep session instances in sync across the cluster. |
---|
| 561 | The implementation of such logic would be to much overhead and cause all |
---|
| 562 | kinds of problems. If your client accesses the same session |
---|
| 563 | simultanously using multiple requests, then the last request |
---|
| 564 | will override the other sessions in the cluster. |
---|
| 565 | </p> |
---|
| 566 | |
---|
| 567 | </blockquote></td></tr></table><table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#525D76"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="Monitoring your Cluster with JMX"><strong>Monitoring your Cluster with JMX</strong></a></font></td></tr><tr><td><blockquote> |
---|
| 568 | <p>Monitoring is a very important question when you use a cluster. Some of the cluster objects are JMX MBeans </p> |
---|
| 569 | <p>Add the following parameter to your startup script with Java 5: |
---|
| 570 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> |
---|
| 571 | set CATALINA_OPTS=\ |
---|
| 572 | -Dcom.sun.management.jmxremote \ |
---|
| 573 | -Dcom.sun.management.jmxremote.port=%my.jmx.port% \ |
---|
| 574 | -Dcom.sun.management.jmxremote.ssl=false \ |
---|
| 575 | -Dcom.sun.management.jmxremote.authenticate=false |
---|
| 576 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> |
---|
| 577 | </p> |
---|
| 578 | <p>Activate JMX with JDK 1.4: |
---|
| 579 | <ol> |
---|
| 580 | <li>Install the compat package</li> |
---|
| 581 | <li>Install the mx4j-tools.jar at common/lib (use the same mx4j version as your tomcat release)</li> |
---|
| 582 | <li>Configure a MX4J JMX HTTP Adaptor at your AJP Connector<p></p> |
---|
| 583 | <div align="left"><table border="0" cellpadding="0" cellspacing="4"><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#ffffff"><pre> |
---|
| 584 | <Connector port="${AJP.PORT}" |
---|
| 585 | handler.list="mx" |
---|
| 586 | mx.enabled="true" |
---|
| 587 | mx.httpHost="${JMX.HOST}" |
---|
| 588 | mx.httpPort="${JMX.PORT}" |
---|
| 589 | protocol="AJP/1.3" /> |
---|
| 590 | </pre></td><td width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr><tr><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td><td height="1" width="1" bgcolor="#023264"><img border="0" hspace="0" vspace="0" height="1" width="1" src="./../images/void.gif"></td></tr></table></div> |
---|
| 591 | </li> |
---|
| 592 | <li>Start your tomcat and look with your browser to http://${JMX.HOST}:${JMX.PORT}</li> |
---|
| 593 | <li>With the connector parameter <code>mx.authMode="basic" mx.authUser="tomcat" mx.authPassword="strange"</code> you can control the access!</li> |
---|
| 594 | </ol> |
---|
| 595 | </p> |
---|
| 596 | <p> |
---|
| 597 | List of Cluster Mbeans<br> |
---|
| 598 | <table border="1" cellpadding="5"> |
---|
| 599 | |
---|
| 600 | <tr> |
---|
| 601 | <th align="center" bgcolor="aqua">Name</th> |
---|
| 602 | <th align="center" bgcolor="aqua">Description</th> |
---|
| 603 | <th align="center" bgcolor="aqua">MBean ObjectName - Engine</th> |
---|
| 604 | <th align="center" bgcolor="aqua">MBean ObjectName - Host</th> |
---|
| 605 | </tr> |
---|
| 606 | |
---|
| 607 | <tr> |
---|
| 608 | <td>Cluster</td> |
---|
| 609 | <td>The complete cluster element</td> |
---|
| 610 | <td><code>type=Cluster</code></td> |
---|
| 611 | <td><code>type=Cluster,host=${HOST}</code></td> |
---|
| 612 | </tr> |
---|
| 613 | |
---|
| 614 | <tr> |
---|
| 615 | <td>DeltaManager</td> |
---|
| 616 | <td>This manager control the sessions and handle session replication </td> |
---|
| 617 | <td><code>type=Manager,path=${APP.CONTEXT.PATH}, host=${HOST}</code></td> |
---|
| 618 | <td><code>type=Manager,path=${APP.CONTEXT.PATH}, host=${HOST}</code></td> |
---|
| 619 | </tr> |
---|
| 620 | |
---|
| 621 | <tr> |
---|
| 622 | <td>ReplicationValve</td> |
---|
| 623 | <td>This valve control the replication to the backup nodes</td> |
---|
| 624 | <td><code>type=Valve,name=ReplicationValve</code></td> |
---|
| 625 | <td><code>type=Valve,name=ReplicationValve,host=${HOST}</code></td> |
---|
| 626 | </tr> |
---|
| 627 | |
---|
| 628 | <tr> |
---|
| 629 | <td>JvmRouteBinderValve</td> |
---|
| 630 | <td>This is a cluster fallback valve to change the Session ID to the current tomcat jvmroute.</td> |
---|
| 631 | <td><code>type=Valve,name=JvmRouteBinderValve, |
---|
| 632 | path=${APP.CONTEXT.PATH}</code></td> |
---|
| 633 | <td><code>type=Valve,name=JvmRouteBinderValve,host=${HOST}, |
---|
| 634 | path=${APP.CONTEXT.PATH}</code></td> |
---|
| 635 | </tr> |
---|
| 636 | |
---|
| 637 | </table> |
---|
| 638 | </p> |
---|
| 639 | </blockquote></td></tr></table><table cellpadding="2" cellspacing="0" border="0"><tr><td bgcolor="#525D76"><font face="arial,helvetica.sanserif" color="#ffffff"><a name="FAQ"><strong>FAQ</strong></a></font></td></tr><tr><td><blockquote> |
---|
| 640 | <p>Please see <a href="http://tomcat.apache.org/faq/cluster.html">the clustering section of the FAQ</a>.</p> |
---|
| 641 | </blockquote></td></tr></table></td></tr><!--FOOTER SEPARATOR--><tr><td colspan="2"><hr size="1" noshade></td></tr><!--PAGE FOOTER--><tr><td colspan="2"><div align="center"><font size="-1" color="#525D76"><em> |
---|
| 642 | Copyright © 1999-2008, Apache Software Foundation |
---|
| 643 | </em></font></div></td></tr></table></body></html> |
---|