zoukankan      html  css  js  c++  java
  • tomcat集群机制剖析及其生产部署选型

    为什么要使用集群?

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

    集群难点在哪?

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

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

     

    全节点会话同步模型

        鉴于统一将会话存放到数据库或缓存上存在的不足,提供还有一种解决思路就是tomcat集群节点自身完毕各自的数据同步,无论訪问到哪个节点都能找到相应的会话。例如以下图,client第一次訪问生成会话。tomcat自身会将会话信息同步到其它节点上,并且是每次请求完毕都会同步此次请求过程中对session的全部操作,这样一来下一次请求到集群中随意节点都能找到响应的会话信息。且能保证信息的及时性。并且随意一个节点宕掉了也不影响总体对外的服务。

     

    会话备份单节点模型

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

        完毕上面一步后就是将会话内容备份到备份节点上,假如tomcat1s1s2两个会话的备份地址为tomcat2,则把会话对象备份到tomcat2中,相似的有tomcat2s3会话备份到tomcat4tomcat4s4s5两个对话备份到tomcat3,这样集群中全部的会话都已经有了一份备份。当tomcat1一直不出故障,由于Session Stick技术client将一直訪问到tomcat1节点上,保证一直能获取到会话。而当tomcat1出故障了。这时tomcat也提供了一个failover机制,apache感知到后端集群tomcat1节点被移除了。这时它会把请求随机分配到其它随意节点上,接下去会有两种情况:

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

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

     

    生产部署选型

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

    对于全节点会话同步模型

    细看非常easy发现集群的节点之间的会话是两两互相复制的,一旦集群节点数量及訪问量大起来。将导致大量的会话信息须要互相复制同步。非常easy导致网络堵塞,并且这些同步操作非常可能会成为总体性能的瓶颈,依据经验。此种方案在实际生产上推荐的集群节点个数为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"/>

    使用这样的模型也要考虑到。尽管这样的模式支持更大的集群。但它仅仅有一个数据备份。假如刚好源数据和备份数据所在的机器同一时候宕掉了,则没办法恢复数据。只是刚好同一时候宕机的机率非常小非常小。


    点击订购作者《Tomcat内核设计剖析》




  • 相关阅读:
    程序员开发过程常见问题的解决方法(持续更新中....)
    android 单元测试
    浅谈android binder机制
    Android 写模块化代码注意事项
    Android View 简析
    PackageManager源码分析
    Android N做了啥
    JAVA HTTP POST参数为一个对象或数组
    Spring+Jetty+Jersey+Mybatis整合教程 无web.xml 、webapp版
    IKAnalyzer 添加扩展词库和自定义词
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/7000843.html
Copyright © 2011-2022 走看看