对于WEB 应用 集群的技术 实现而言,最大的难点就是如何能在集群中的多个节点之间保持数据 的一致性,会话(Session)信息是这些数据中最重要的一块。要实现这一点,大体上有两种方式,一种是把所有Session数据放到一台服务器 上或者数据库 中,集群中的所有节点通过访问 这台Session服务 器来获取数据;另一种就是在集群中的所有节点间进行Session数据的同步拷贝,任何一个节点均保存了所有的Session数据。两种方式都各有优点, 第一种方式简单、易于实现,但是存在着Session服务器发生故障会导致全系统 不能正常工作的风险;第二种方式可靠性更高,任一节点的故障不会对整个系统对客户访问的响应产生影响,但是技术实现上更复杂一些。常见的平台或中间件如 microsoft asp.net和IBM WAS都会提供对两种共享方式的支持,tomcat也是这样,但是一般采用第二种方式。
当采用tomcat默认集群配置(<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>)时,配置的细节实际上被 省略了,对于大多数应用而言,使用默认配置已经足够,完整的默认配置应该是这样:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="8">
<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>
<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"
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"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=""/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
下面笔者对这里的配置项作详细解释,以下内容均是笔者阅读了tomcat官方文档 后自己的理解,有些可能不对,希望读者能带着批判的眼光阅读,并欢迎指正笔者错误。
tomcat集群各节点通过建立tcp链接来完成Session的拷贝,拷贝有同步和异步两种模式。在同步模式下,对客户端的响应必须在 Session拷贝到其他节点完成后进行;异步模式无需等待Session拷贝完成就可响应。异步模式更高效,但是同步模式可靠性更高。同步异步模式由 channelSendOptions参数控制,默认值是8,为异步模式,4是同步模式。在异步模式下,可以通过加上拷贝确认(Acknowledge) 来提高可靠性,此时channelSendOptions设为10。
Manager用来在节点间拷贝Session,默认使用DeltaManager,DeltaManager采用的一种all-to-all的工 作方式,即集群中的节点会把Session数据向所有其他节点拷贝,而不管其他节点是否部署了当前应用。当集群中的节点数量很多并且部署着不同应用时,可 以使用BackupManager,BackManager仅向部署了当前应用的节点拷贝Session。但是到目前为止BackupManager并未 经过大规模测试,可靠性不及DeltaManager。
Channel负责对tomcat集群的IO层进行配置。Membership用于发现集群中的其他节点,这里的address用的是组播地址 (Multicast address,了解更多组播地址详情请参见 ),使用同一个组播地址和端口 的多个节点同属一个子集群,因此通过自定义组播地址和端口就可将一个大的tomcat集群分成多个子集群。Receiver用于各个节点接收其他节点发送 的数据,在默认配置下tomcat会从4000-4100间依次选取一个可用的端口进行接收,自定义配置时,如果多个tomcat节点在一台物理服务器上 注意要使用不同的端口。Sender用于向其他节点发送数据,具体实现通过Transport配置,PooledParallelSender是从tcp 连接池中获取连接,可以实现并行发送,即集群中的多个节点可以同时向其他所有节点发送数据而互不影响。Interceptor有点类似下面将要解释的 Valve,起到一个阀门的作用,在数据到达目的节点前进行检测或其他操作,如TcpFailureDetector用于检测在数据的传输过程中是否发生 了tcp错误。关于Channel的编程模型,请参见 。
Valve用于在节点向客户端响应前进行检测或进行某些操作,ReplicationValve就是用于用于检测当前的响应是否涉及Session 数据的更新,如果是则启动Session拷贝操作,filter用于过滤请求,如客户端对图片,css,js的请求就不会涉及Session,因此不需检 测,默认状态下不进行过滤,监测所有的响应。JvmRouteBinderValve会在前端的Apache mod_jk发生错误时保证同一客户端的请求发送到集群的同一个节点,tomcat官方文档并未解释如何实现这一点,而且笔者认为这一设置 似乎并无多大实用性。
Deployer用于集群的farm功能 ,监控应用中文件 的更新,以保证集群中所有节点应用的一致性,如某个用户 上传文件到集群中某个节点的应用程序 目录下,Deployer会监测到这一操作并把这一文件拷贝到集群中其他节点相同应用的对应目录下以保持所有应用的一致。这是一个相当强大的功能,不过很 遗憾,tomcat集群目前并不能做到这一点,开发 人员正在努力实现它,这里的配置只是预留了一个接口。
Listener用于跟踪集群中节点发出和收到的数据,也有点类似Valve的功能。
在大体了解了tomcat集群实现模型后,就可以对集群作出更优化的配置了,tomcat推荐 了一套配置,使用了比DeltaManager更高效的BackupManager,并且对ReplicationValve设置了请求过滤,注意在一台 服务器部署多个节点时需要修改Receiver的侦听端口,另外,为了更高效的在节点间拷贝数据,所有tomcat节点最好采用相同的配置,具体配置如 下:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="6">
<Manager className="org.apache.catalina.ha.session.BackupManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"
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="5000"
selectorTimeout="100"
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"/>
<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;"/>
<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
Tomcat集群除了可以进行Session数据的拷贝,还可进行Context属性的拷贝,通过修改context.xml的Context配置 可以实现,使用<Context className="org.apache.catalina.ha.context.ReplicatedContext"/>替换默认 Context即可,当然也可再加上distributable="true"属性。
下面通过假想的一组场景来描述tomcat集群如何工作,集群采用默认配置,由t1和t2两个tomcat例程组成,场景按照时间 顺序排列。
1. t1启动
t1按照标准的tomcat启动,当Host对象被创建时,一个Cluster对象(默认配置下是SimpleTcpCluster)也同时被关联 到这个Host对象。当某个应用在web.xml中设置了distributable时,Tomcat将为此应用的上下文环境创建一个 DeltaManager。SimpleTcpCluster启动membership服务和Replication服务(用于建立tcp连接)。
2. t2启动(待t1启动完成后)
首先t2会执行和t1一样的操作,然后SimpleTcpCluster会建立一个由t1和t2组成的membership。接着t2向集群中已启 动的服务器即t1请求Session数据,如果t1没有响应t2的拷贝请求,t2会在60秒后time out。在Session数据拷贝完成之前t2不会接收客户端的http或mod_jk/ajp请求。
3. t1接收http请求,创建Session s1
t1正常响应客户请求,但是在t1把结果发送回客户端时,ReplicationValve会拦截当前请求(如果filter中配置了不需拦截的请 求类型,这一步就不会进行,默认配置下拦截所有请求),如果发现当前请求更新了Session,调用Replication服务建立tcp连接把 Session拷贝到membership列表中的其他节点即t2,返回结果给客户端(注意,如果采用同步拷贝,必须等拷贝完成后才会返回结果,异步拷贝 在数据发送到tcp连接就返回结果,不等待拷贝完成)。在拷贝时,所有保存在当前Session中的可序列化的对象都会被拷贝,而不仅仅是发生更新的部 分。
4. t1崩溃
当t1崩溃时,t2会被告知t1已从集群中退出,然后t2就会把t1从自己的membership列表中删除 ,发生在t2的Session更新不再往t1拷贝,同时负载均衡器会把后续的http请求全部转发给t2。在此过程中所有的Session数据不会丢失。
5. t2接收s1的请求
t2正常响应s1的请求,因为t2保存着s1的所有数据。
6. t1重新启动
按步骤1、2一样的操作启动,加入集群,从t2拷贝所有Session数据,拷贝完成后开放自己的http和mod_jk/ajp端口接收请求。
7. t1接收请求,s1失效
t1继续接收来自s1的请求,把s1设置为过期。这里的过期并非因为s1处于非活动状态超过设置的时间,而是执行类似注销的操作而引起的 Session失效。这时t1并非发送s1的所有数据而是一个类似s1 expired的消息,t2收到消息后也会把s1设为过期。
8. t2接收请求,创建Session s2
和步骤3一样。
9. t1 s2过期
对于因超时引起的Session失效t1无需通知t2,因为t2同样知道s2已经超时。因此对于tomcat集群有一点非常重要,所有节点的操作系 统 时间必须一致!不然会出现某个节点Session已过期而在另一节点此Session仍处于活动状态的现象。
分享到:
相关推荐
【标题】:“Tomcat Cluster” 在Java应用服务器领域,Tomcat是广泛使用的开源Servlet容器,而Tomcat Cluster则是在单一Tomcat服务器的基础上实现高可用性和负载均衡的一种技术。集群(Cluster)是通过将多个独立的...
http://618119.com/docs/Tomcat/TomcatCluster.zip 下载解压到Tomcat(例如D:\Java\apache-tomcat-6.0.14)目录里,运行对应的bat文件即可: start15080.bat start16080.bat start17080.bat start18080.bat start...
【标题】:“Tomcat集群(Cluster)参考资料3” 在Java Web开发中,Apache Tomcat作为一款广泛应用的开源Servlet容器,其集群(Cluster)功能对于处理高并发、提供高可用性和负载均衡至关重要。Tomcat Cluster是...
"tomcat9+tomcat-cluster-redis-session-manager_4.0.zip"这个文件组合涉及到的是在Tomcat 9上实现负载均衡以及使用Redis作为Session管理器的高级配置。 首先,Tomcat 9是Apache Tomcat服务器的一个版本,它是Java ...
tomcat7 的集群session共享 案例 亲测可用 无效联系我:351137017
tomcat cluster sync-session利用exp 这是一个tomcat使用了自带会话同步功能时,不安全的配置(没有使用EncryptInterceptor)导致存在的反序列化漏洞,通过精心构造的数据包,可以对使用了tomcat自带会话同步功能的...
在 Apache 中,通过 `ProxyPass` 和 `ProxyPassReverse` 指令将所有请求转发到 `balancer://tomcatcluster`,这样 Apache 就会根据负载均衡策略将请求分发给后端的 Tomcat 实例。`stickysession` 参数用于保持用户...
基于Xen虚拟机实现Apache Tomcat集群搭建的知识点如下: 1. Xen虚拟机技术:Xen是一个开源的虚拟机监视器,允许用户在同一台物理主机上运行多个虚拟机,每个虚拟机可以运行不同的操作系统。Xen具有高性能和高扩展性...
apache + tomcat 集群配置,实现了,负载均衡,session复制。
在这个特定的压缩包"apache-tomcat-8.5.55.zip"中,我们看到它已经集成了 "tomcat-cluster-redis-session-manager 4.0"。这个集成意味着Tomcat已经配置了使用Redis作为会话管理器的集群解决方案。 会话管理是Web...
使用redis配置tomcat共享会话tomcat-redis-会话管理器使用redis配置tomcat共享会话结构图分析分布式web server集群部署后需要实现session共享,针对 tomcat 服务器的实现方案多种多样,比如 tomcat cluster session ...
nginx做请求转发,服务器tomcat解决session不同步问题;步骤:1、解压之后,将jar包放入tomcat的lib中(注意是tomcat/lib中,不是我们自己项目的lib);2、配置解压之后的redis-data-cache.properties(根据你的...
实现这一功能需要替换或升级Tomcat的lib目录下的相关jar包,比如`tomcat-coyote.jar`、`tomcat-cluster.jar`等,并在`server.xml`中配置Cluster元素,设置集群通信参数和Session复制策略。 4. **Spring Session**:...
- 集群名: `balancer://tomcatcluster` - IP 地址: - IP_1: 192.168.1.31 - IP_2: 192.168.1.32 - IP_3: 192.168.1.33 - 测试应用程序位置: `/usr/local/tomcat6/webapps/test` - 操作系统: CentOS 4.5_x86 ...
【标题】:“Tomcat 8+ Redis Cluster Session” 在现代Web应用开发中,session管理是不可或缺的一部分,尤其是在分布式系统中。传统的session管理方式在多台服务器之间存在数据同步问题,导致用户状态无法共享,...
分布式web server集群部署后需要实现session共享,针对 tomcat 服务器的实现方案多种多样,比如 tomcat cluster session 广播、nginx IP hash策略、nginx sticky module等方案,本文主要介绍了使用 redis 服务器进行...
网站架构是,通过一个apache+多个tomcat和mysql的结 构。client的安装脚本。
### Tomcat Apache Cluster 脚本知识点解析 #### 一、Tomcat与Apache集群配置概述 在企业级应用环境中,为了提升系统的可用性、可扩展性和性能,常常需要对服务器进行集群部署。其中,Apache与Tomcat的组合是一种...