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的同学交个朋友:
tomcat集群机制剖析及其生产部署选型的更多相关文章
- tomcat集群实现源码级别剖析
随着互联网快速发展,各种各样供外部访问的系统越来越多且访问量越来越大,以前Web容器可以包揽接收-逻辑处理-响应整个请求生命周期的工作,现在为了构建让更多用户访问更强大的系统,人们通过不断地业务解耦. ...
- Tomcat集群应用部署的实现机制
集群应用部署是一个很重要的应用场景,设想一下如果没有集群应用部署功能,每当我们发布应用时都要登陆每台机器对每个tomcat实例进行部署,这些工作量都是繁杂且重复的,而对于进步青年的程序员来说是不能容忍 ...
- FineReport关于tomcat集群部署的方案
多台服务器集群后,配置权限.数据连接.模板.定时调度等,只能每台服务器一个个配置,不会自动同步到所有服务器. 针对上述情况,在FineReport中提供新集群部署插件,将xml配置文件.finedb/ ...
- Nginx+Tomcat集群部署
为了获取更好的性能,我们常常需要将tomcat进行集群部署.下文通过nginx转发实现tomcat集群,并通过nginx-upstream-jvm-route插件保证session的粘滞. 应用场景环 ...
- 【转】Tomcat集群Cluster实现原理剖析
此文章来源:http://zyycaesar.iteye.com/blog/296606 此文章作者:zyycaesar 对于WEB应用集群的技术实现而言,最大的难点就是如何能在集群中的多个节点之间保 ...
- 使用Tomcat-redis-session-manager来实现Tomcat集群部署中的Session共享
一.工作中因为要使用到Tomcat集群部署,此时就涉及到了Session共享问题,主要有三种解决方案: 1.使用数据库来存储Session 2.使用Cookie来存储Session 3.使用Redis ...
- Docker Compose 一键部署Nginx代理Tomcat集群
Docker Compose 一键部署Nginx代理Tomcat集群 目录结构 [root@localhost ~]# tree compose_nginx_tomcat/ compose_nginx ...
- Docker Compose部署 nginx代理Tomcat集群
一.简介 使用Docker镜像部署Nginx代理的多个Tomcat集群: 使用Dockerfile构建nginx镜像 使用Dockerfile构建tomcat镜像 mysql镜像使用docker hu ...
- Tomcat集群环境下session共享方案 通过memcached 方法实现
对于web应用集群的技术实现而言,最大的难点就是:如何能在集群中的多个节点之间保持数据的一致性,会话(Session)信息是这些数据中最重要的一块.要实现这一点, 大体上有两种方式:一种是把所有Ses ...
随机推荐
- Java中Semaphore(信号量)的使用
Semaphore的作用: 在java中,使用了synchronized关键字和Lock锁实现了资源的并发访问控制,在同一时间只允许唯一了线程进入临界区访问资源(读锁除外),这样子控制的主要目的是为了 ...
- 整理的Java List Set Map是否有序,元素是否允许重复
整理的Java List Set Map是否有序,元素是否允许重复的说明,如下图:
- 《读书报告 -- Elasticsearch入门 》-- 安装以及简单使用(1)
<读书报告 – Elasticsearch入门 > 第一章 Elasticsearch入门 Elasticsearch是一个实时的分布式搜索和分析引擎,使得人们可以在一定规模上和一定速度上 ...
- RX系列四 | RxAndroid | 加载图片 | 提交表单
RX系列四 | RxAndroid | 加载图片 | 提交表单 说实话,学RxJava就是为了我们在Android中运用的更加顺手一点,也就是RxAndroid,我们还是先一步步来,学会怎么去用的比较 ...
- 六星经典CSAPP-笔记(12)并发编程(上)
六星经典CSAPP-笔记(12)并发编程(上) 1.并发(Concurrency) 我们经常在不知不觉间就说到或使用并发,但从未深入思考并发.我们经常能"遇见"并发,因为并发不仅仅 ...
- 微信小程序基础之创建使用教程
本文档将带你一步步创建完成一个微信小程序,并可以在手机上体验该小程序的实际效果.这个小程序的首页将会显示欢迎语以及当前用户的微信头像,点击头像,可以在新开的页面中查看当前小程序的启动日志. 1. 获取 ...
- 基于BaseAdapter的Listview小Demo
ListView是android开发中比较常用的控件, 其中适配器模式可以选择: ArrayAdapter:简单易用,通常用于将数组或者List集合的读个包值封装成多个列表项 SimpleAdapte ...
- SQL 数据库语言分析总结(三)
这次介绍通过mysql-WorkBench这个工具来管理操作数据库. 创建和删除数据库 1.点击创建数据库按钮 2.选中后右键,出现drop schema一项,这个用来删除. 设置默认数据库 选中右键 ...
- Android简易实战教程--第十话《模仿腾讯手机助手小火箭发射详解》
之前对系统自带的土司的源码做了简要分析,见博客:点击打开链接 这一篇给一个小案例,自定义土司,模拟腾讯卫士的小火箭发射.如果想要迅速看懂代码,建议先去看一下上篇介绍点击打开链接 首先,定义一个服务,在 ...
- java的list几种实现方式的效率(ArrayList、LinkedList、Vector、Stack),以及 java时间戳的三种获取方式比较
一.list简介 List列表类,顺序存储任何对象(顺序不变),可重复. List是继承于Collection的接口,不能实例化.实例化可以用: ArrayList(实现动态数组),查询快(随意访问或 ...