tomcat集群机制剖析及其生产部署选型

为什么要使用集群?

为什么要使用集群?主要有两方面原因:一是对于一些核心系统要求长期不能中断服务,为了提供高可用性我们需要由多台机器组成的集群;另外一方面,随着访问量越来越大且业务逻辑越来越复杂,单台机器的处理能力已经不足以处理如此多且复杂的逻辑,于是需要增加若干台机器使整个服务处理能力得到提升。

集群难点在哪?

如果说一个web应用不涉及会话的话,那么做集群是相当简单的,因为节点都是无状态的,集群内各个节点无需互相通信,只需要将各个请求均匀分配到集群节点即可。但基本所有web应用都会使用会话机制,所以做web应用集群时整个难点在于会话数据的同步。

当然你可以通过一些策略规避复杂的额数据同步操作,例如前面说到的把会话信息保存在分布式缓存或数据库中统一集中管理,如下图,每个tomcat实例只需去写入或读取数据库即可,避免了tomcat集群之间的通信。但这种方式也有不足,要额外引入数据库或缓存服务,同时也要保证它们的高可用性,增加了机器和维护成本。

全节点会话同步模型

鉴于统一将会话存放到数据库或缓存上存在的不足,提供另一种解决思路就是tomcat集群节点自身完成各自的数据同步,不管访问到哪个节点都能找到对应的会话,如下图,客户端第一次访问生成会话,tomcat自身会将会话信息同步到其他节点上,而且是每次请求完成都会同步此次请求过程中对session的所有操作,这样一来下一次请求到集群中任意节点都能找到响应的会话信息,且能保证信息的及时性。而且任意一个节点宕掉了也不影响整体对外的服务。

会话备份单节点模型

Tomcat提供的第二种集群会话管理的机制就是单节点备份机制,下面看看这种方式具体的工作机制,集群一般是通过负载均衡对外提供整体服务,所有节点被隐藏在后端组成一个整体。前面各种模式的实现都无需负载均衡协助,所以图中都把负载均衡省略了。最常见的负载方式是前面用apache拖所有节点,它支持将类似“326257DA6DB76F8D2E38F2C4540D1DEA.tomcat1”的会话id进行分解,定位到tomcat集群中以tomcat1命名的节点上(这种方式称为Session Stick,由apache jk模块实现)。每个会话存在一个原件和一个备份,且备份与原件不会保存在同一个节点上,如下图,例如当客户端发起请求后通过负载均衡被分发到tomcat1实例节点上,生成一个包含.tomcat1后缀的会话标识,并且tomcat1节点根据一定策略选出此次会话对象备份的节点,然后将包含了{会话id,备份ip}的信息发送给tomcat2、tomcat3、tomcat4,如图中虚线所示,这样每个节点都有一个会话id、备份ip列表,即每个节点都有每个会话的备份ip地址。

完成上面一步后就是将会话内容备份到备份节点上,假如tomcat1的s1、s2两个会话的备份地址为tomcat2,则把会话对象备份到tomcat2中,类似的有tomcat2把s3会话备份到tomcat4,tomcat4把s4、s5两个对话备份到tomcat3,这样集群中所有的会话都已经有了一份备份。当tomcat1一直不出故障,由于Session Stick技术客户端将一直访问到tomcat1节点上,保证一直能获取到会话。而当tomcat1出故障了,这时tomcat也提供了一个failover机制,apache感知到后端集群tomcat1节点被移除了,这时它会把请求随机分配到其他任意节点上,接下去会有两种情况:

①刚好分到了备份节点tomcat2上,此时仍能获取到s1会话,除此之外,tomcat2还要另外做的事是将这个s1会话标记为原件且继续选取一个备份地址备份s1会话,这样一来又有了备份。

②假如分到了非备份节点tomcat3,此时肯定找不到s1会话,于是它将向集群所有节点发问,“请问谁有s1会话的备份ip地址信息?”,因为只有tomcat2有s1的备份地址信息,它接收到询问后应答告知tomcat3节点s1会话的备份在tomcat2,根据这个信息就能查到s1会话了,并且tomcat3在自己本地生成s1会话并标为原件,tomcat2上的副本不变,这样一来同样能找到s1会话,正常完整整个请求处理。

生产部署选型

以上两种模型都有各自的优缺点,在实际生产上部署应该根据实际情况选择适合的模型。

对于全节点会话同步模型

细看很容易发现集群的节点之间的会话是两两互相复制的,一旦集群节点数量及访问量大起来,将导致大量的会话信息需要互相复制同步,很容易导致网络阻塞,而且这些同步操作很可能会成为整体性能的瓶颈,根据经验,此种方案在实际生产上推荐的集群节点个数为3-6个,它无法组建更大的集群,而且冗余了大量的数据,利用率较低。

对于集群增量会话管理器,可通过配置server.xml文件使用它,在tomcat中使用集群模式需要在<Engine>节点下添加<cluster>节点,而集群增量会话管理器正是在此节点下添加一个子节点<Manager className="org.apache.catalina.ha.session.DeltaManager"/>。

对于会话备份模型

针对上面全节点会话同步模型的网络流量随节点数量增加呈平方趋势增长的问题,也正是因为这个因素导致无法构建较大规模的集群,为了使集群节点能更加大,首要解决的就是数据复制时流量增长的问题,tomcat提出会话备份模型对前面的模型进行优化,它使会话备份的网络流量随节点数量的增加呈线性趋势增长,每个会话只会有一个备份,大大减少了网络流量和逻辑操作,此模型可构建较大的集群。生产上可以组成十个以上的节点作为一个集群。

对于集群备份会话管理器,可通过配置server.xml文件使用它,它的配置与DeltaManager的配置基本相似,在<cluster>节点下添加一个子节点<Manager className="org.apache.catalina.ha.session.BackupManager"/>。

使用这种模型也要考虑到,虽然这种模式支持更大的集群,但它只有一个数据备份,假如刚好源数据和备份数据所在的机器同时宕掉了,则没办法恢复数据,不过刚好同时宕机的机率很小很小。

喜欢java的同学交个朋友:

时间: 2025-01-12 04:47:39

tomcat集群机制剖析及其生产部署选型的相关文章

tomcat集群实现源码级别剖析

随着互联网快速发展,各种各样供外部访问的系统越来越多且访问量越来越大,以前Web容器可以包揽接收-逻辑处理-响应整个请求生命周期的工作,现在为了构建让更多用户访问更强大的系统,人们通过不断地业务解耦.架构解耦将web容器的逻辑处理抽离交由其他中间件处理,例如缓存中间件.消息队列中间件.数据存储中间件等等.Web容器负责的工作可能越来越少,但是它确实必不可少的部分,它负责接收用户请求并分别调用各个服务最后响应.可以说目前最受欢迎的web容器是用Java写的tomcat小猫,由于生产上的tomcat

Tomcat集群应用部署的实现机制

集群应用部署是一个很重要的应用场景,设想一下如果没有集群应用部署功能,每当我们发布应用时都要登陆每台机器对每个tomcat实例进行部署,这些工作量都是繁杂且重复的,而对于进步青年的程序员来说是不能容忍重复的事情发生的.于是需要一种功能可以在集群中某实例部署后,集群中的其他tomcat实例会自动完成部署. 集群部署主要分两部分内容. 第一部分是关于应用传输问题,主要是关于在tomcat中如何一个web应用传输到其它tomcat实例上: 第二部分是应用部署方式及应用更新方式,主要关于在tomcat中

Nginx+Tomcat 集群部署

1.Nginx + Tomcat 集群部署 简单配置 1 #user nobody; 2 worker_processes 4;#工作进程的个数 3 4 #error_log logs/error.log; 5 #error_log logs/error.log notice; 6 #error_log logs/error.log info; 7 8 #pid logs/nginx.pid; 9 10 11 events { 12 worker_connections 1024; #单个进程连

FineReport关于tomcat集群部署的方案

多台服务器集群后,配置权限.数据连接.模板.定时调度等,只能每台服务器一个个配置,不会自动同步到所有服务器. 针对上述情况,在FineReport中提供新集群部署插件,将xml配置文件.finedb/logdb数据(定时任务.报表目录管理.批量导入.统计信息)的修改都对主机生效.其他辅机的信息读取也都从主机读取,保证了数据同步. 实现了灾备,即主机当即后,次主机会上位接替主机的工作,保证系统正常运作. 同时还增加了集群灾备之文件同步,会将主机的finedb.xml.模板.jar包.插件等等备份到

Nginx+Tomcat集群部署

为了获取更好的性能,我们常常需要将tomcat进行集群部署.下文通过nginx转发实现tomcat集群,并通过nginx-upstream-jvm-route插件保证session的粘滞. 应用场景环境: server1 服务器上安装了 nginx + tomcat01 server2 服务器上只安装了 tomcat02 server1 IP 地址: 192.168.1.88 server2 IP 地址: 192.168.1.89 安装步骤: 1)在server1 上安装配置 nginx + n

apache tomcat 集群 负债均衡 部署

Apache + Tomcat 配置负载均衡 此文档内容已经经过测试 JavaSDK版本: 1.6.20 Apache版本: 2.2.15    http://httpd.apache.org/ Tomcat版本: apache-tomcat-6.0.35 http://tomcat.apache.org/download-60.cgi ====================================安装javaSDK就默认安装了. apache的安装没有什么特别的,一路下一步即可,当然

Docker Compose 一键部署Nginx代理Tomcat集群

Docker Compose 一键部署Nginx代理Tomcat集群 目录结构 [[email protected] ~]# tree compose_nginx_tomcat/ compose_nginx_tomcat/ ├── docker-compose.yml ├── mysql │   ├── conf │   │   └── my.cnf │   └── data ├── nginx │   ├── Dockerfile │   ├── nginx-1.12.1.tar.gz │  

使用Tomcat-redis-session-manager来实现Tomcat集群部署中的Session共享

一.工作中因为要使用到Tomcat集群部署,此时就涉及到了Session共享问题,主要有三种解决方案: 1.使用数据库来存储Session 2.使用Cookie来存储Session 3.使用Redis来存储Sesssion 4.使用Tomcat的session复制 5.使用Memcached来存储Session 二.本文中主要讲一下第3种方案,也就是使用Redis来存储Session,Github中已经有该开源组件(Tomcat-redis-session-manager),下面讲一下配置的步骤

Docker部署Nginx、Tomcat集群

Tomcat集群由多个tomcat组成,使用Nginx的好处是可以实现负载均衡和动静分离.使用Docker的好处是~~~我们不需要复杂的配置,只需要执行简单的命令就能拉取已有的官方docker镜像,再通过一条命令就能运行我们的实例了.对于多个Tomcat,我们使用相同的镜像,然后使用简单的命令,就能创建不同的tomcat container实例. 1.拉去镜像 $ docker pull tomcat:8-jre8-alpine $ docker pull nginx:latest $ dock