要在Tomcat 5.5容器里进行session复制,必须完成下列步骤:
所有会话属性值必须实现java.io.Serializable
把server.xml文件里的群集(Cluster)元素的注释取消(Uncomment)
把server.xml文件里的Valve(ReplicationValve)元素注释取消(Uncomment)
如果有多个Tomcat实例在一台机器上运行,确保每个实例的tcpListenPort属性值是不冲突的。
确定 web.xml 中含有 <distributable/> 元素, 或者设置 <Context distributable=\"大众true\"大众 />
确定设置好Engine元素的 jvmRoute 的属性值: <Engine jvmRoute=\"大众node01\"大众 >
确定所有节点拥有相同的韶光, 并且通过网络韶光做事(NTP)同步操作系统的韶光!
确定负载均衡器已经配置为黏性会话模式.
把稳:记住你的会话状态是被一个cookie跟踪的,以是你的URL从表面看必须是相同的,否则一个新的session就会被产生。
把稳:集群支持目前须要JDK 1.4或其后版本。
要在Tomcat里实现会话session复制,下面三种方法都可以实现相同效果:
利用session 持久化, 并将 session 保存到一个共享的文件系统(持久管理器 + 文件存储)
利用session 持久化, 并将 session 保存到一个共享的 数据库 (持久管理器 + JDBC存储)
利用in-memory-replication,利用和Tomcat 5自带的SimpleTcpCluster(server/lib/catalina-cluster.jar)
运用处景:
在这个场景中,操持利用两个tomcat 实例 TomcatA 和 TomcatB. 我们将覆盖下面连续的事宜:
TomcatA 接管一个要求,session S1 被产生,TomcatB 接管一个session S1的要求 ,TomcatA 接管一个要求,session ( S1 )失落效。 TomcatB 接管一个新的session ( S2 )的要求。 TomcatA 由于没有活动session S2过期失落效。
在session复制时期码里发生的所有事情
1)Tomcat 标准办法启动
当 Host 工具被创建之后, 一个 cluster 工具与它关联. 当高下文被解析完, 如果 web.xml中有distributable元素, Tomcat 通过 Cluster class (in this case SimpleTcpCluster)为支持复制的高下文创建一个管理器. 因此通过设置web.xml中的distributable来启用集群。 Tomcat 将为高下文创建 DeltaManager莱取代 StandardManager. cluster class 将启动 a membership service (multicast) 和 a replication service (tcp unicast). More on the architecture further down in this document.
2)TomcatB 启动
当TomcatB启动时,除了一个例外以外,它按照TomcatA一样的顺序启动。群集被启用,并将建立一组会员(TomcatA,TomcatB)。TomcatB现在将要request已经存在于群集里的做事器的会话状态,在这里这个做事器是TomcatA。TomcatA回应TomcatB的要求,并且在TomcatB开始为HTTP requests监听之前,这个状态已经由TomcatA通报给TomcatB了。在TomcatA不回应的情形下,TomcatB在60秒后中断,并发出一个日志记录。对付每个已经分布在web.xml里的web运用程序,会话状态会被转移。把稳:要有效地利用会话复制,你的所有tomcat实例要配置成一样的。
3)TomcatA 接管一个要求,session S1 被产生。
TomcatA对待通报来的要求与对待没有会话复制一样。当要求完成往后,活动就开始了,ReplicationValve在回应被返回到用户那里之前会截断这个要求。在这时,它创造会话被修正过,它就用TCP把这个会话复制给TomcatB。一旦这个分段的数据被递交给操作系统TCP logic,要求就通过valve pipeline返回给用户。对付每个要求,全体会话都被复制,这许可在不调用setAttribute 或 removeAttribute情形下,在会话中修正属性的代码被复制。配置参数useDirtyFlag可以被用来优化会话复制的次数。
4)TomcatA崩溃
当TomcatA崩溃时,TomcatB会收到关照说TomcatA已经退出群集。TomcatB把TomcatA从它的会员列单中删除掉,TomcatB里有任何变动也不会再关照TomcatA。装载均衡器会把对TomcatA的要求引向TomcatB以及所有当前活动会话。
5)TomcatB 接管一个session S1的要求
TomcatB像处理其他任何要求一样处理这个要求。
TomcatA启动时,在它接管新的要求以及让它自己可被利用之前,它要按照上面 1) 2)中所描述的顺序进行启动。它会加入群集,与TomcatB联系,理解所有会话确当前状态。一旦它接管到会话状态,它就完成装载并打开它的HTTP/mod_jk ports。以是在TomcatA接管到来自TomcatB的会话状态之前,不会对它发出要求。
6)TomcatA 接管一个要求,session ( S1 )失落效。
失落效的呼叫被拦截,这个会话就加入到失落效的会话行列。在这个要求完成往后,它向TomcatB发出一个\"大众expire\"大众信息,TomcatB也把这个会话变为失落效。
7)TomcatB 接管一个新的session ( S2 )的要求。
与步骤3)环境一样。
8)TomcatA 由于没有活动session S2过期失落效。
就如一个会话由用户让它无效一样,invalidate呼叫被拦截到,这个会话就加入失落效的会话行列。这一点上,除非另一个要求通过系统来检讨失落效行列,会话失落效不会在其他地方重复。
Phuuuhh! :)
Membership Clustering membership可以通过利用非常大略的multicast pings被建立。每个Tomcat实例定期会发出multicast ping,在ping message里,这个实例会散布它的IP 及 TCP 监听端口以用于复制。如果一个实例在所给的韶光范围内还没有收到这样的ping,这个会员就被认为是不存在了。很大略,也很有效。当然,你须要在你的系统上让multicasting可被利用。
TCP Replication,在收到一个multicast ping往后,会员就被添加到群集里。不才一个复制要求时,发出要求的实例将利用host和port信息来建立一个TCP socket。通过利用这个socket,它把分段的数据发送过去。选择TCP sockets 的缘故原由是它具备有流量掌握,并确保发送到位。当发送数据时,这个数据就会被送到。
Distributed locking and pages using frames: Tomcat 并没有让会话实例在群集之间保持同等。这个逻辑的实现须要太大空间,也会带来很多问题。如果你的客户利用多个要求同时访问同一个会话,那么末了一个要求会覆盖群集里的其它会话。