tomcat4----集群会话复制

tomcat4----集群会话复制

tomcat集群会话复制

基于多播通信的方式,把会话信息同步给后端其他节点,这个组件就是 cluster

概述

要在 Tomcat 中启用会话复制,可以遵循三种不同的路径来实现完全相同的目标:
1、使用会话持久性,并将会话保存到共享文件系统(PersistenceManager + FileStore)
2、使用会话持久化,并将会话保存到共享数据库(PersistenceManager + JDBCStore)
3、 使用内存复制,使用 Tomcat 附带的 SimpleTcpCluster (lib/catalina-tribes.jar + lib/catalina-ha.jar)

        DNS Round Robin
               |
         Load Balancer
          /           \
      Cluster1      Cluster2
      /     \        /     \
  Tomcat1 Tomcat2  Tomcat3 Tomcat4

应用程序

  • stateful:有状态
    扩展:负载均衡,每一个个体是不可被取代,2个MYSQL,两批不同的用户连接不同的MYSQL数据存储,他们能互相取代吗?做不到,但是如果两个静态WEB服务器,指向同一种存储,任何服务都可以取到数据,因此,不用当个体来看待,就当群体看待,任何一个都可以被 取代
  • stateless:无状态

翻译:无状态为畜牲,有状态则为宠物,不可取代,很难被取代,因此,扩展受到了限制,无状态没有任何的限制

集群基础

  • 您的所有会话属性都必须实现 java.io.Serializable
  • 取消注释Clusterserver.xml 中的元素
  • 如果您已定义自定义集群阀,请确保ReplicationValve 在 server.xml 中的 Cluster 元素下也已定义
  • 如果您的 Tomcat 实例在同一台机器上运行,请确保Receiver.port 每个实例的属性都是唯一的,在大多数情况下,Tomcat 足够聪明,可以通过自动检测 4000-4100 范围内的可用端口自行解决此问题
  • 确保你web.xml有 元素
  • 如果您使用的是 mod_jk,请确保在您的引擎中设置<Engine name="Catalina" jvmRoute="node01" >了 jvmRoute 属性,并且 jvmRoute 属性值与您在workers.properties 中的工作人员名称相匹配
  • 确保所有节点具有相同的时间并与 NTP 服务同步!
  • 确保您的负载均衡器配置为粘性会话模式

注意:请记住,您的会话状态由 cookie 跟踪,因此您的 URL 必须从外部看起来相同,否则将创建一个新会话。

示例:使用 tomcat cluster 组件来定义 tomcat 的会话复制集群,服务器节点变动会不会影响用户的会话

官方文档:https://tomcat.apache.org/tomcat-8.5-doc/cluster-howto.html
只需添加在<Engine><Host>元素以启用集群

server.xml配置文件

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8"> #Cluster 内部定义,<Cluster>元素放置在<Engine> 容器或<Host>容器内,对Engine或Host应用
          <Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/> #Manager 会话管理器,标识在此集群实现中使用哪种类型的会话管理器,此管理器配置与您在常规<Context>配置中使用的配置相同
          <Channel className="org.apache.catalina.tribes.group.GroupChannel">	#Channel 信道,此处表示做集群成员关系判定,并不是在多播地址中就是一个群集成员,而是根据信道内部其他属性定义进行成员判定
            <Membership className="org.apache.catalina.tribes.membership.McastService"	#实现使用多播心跳进行成员发现
                        address="228.0.0.4"	#成员将广播其存在并侦听其他心跳的多播地址
                        port="45564"	#组播端口
                        frequency="500"	#发送心跳的频率(以毫秒为单位)。默认值为500毫秒
                        dropTime="3000"/>	#如果成员未能在给定时间内发送心跳,则成员资格组件将使成员超时并通知频道。默认值为3000毫秒。这意味着,如果在该时间范围内没有收到来自成员的心跳,成员资格组件将通知集群(在高延迟网络上,您可能希望增加此值,以防止误报)
            <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"	#Recevier 接收器,接收别人发过来的session
                      address="auto"  #	侦听传入流量的地址(网络接口),默认为auto,建议指定网络接口的IP(确保你没有广播 127.0.0.1,这是一个常见的错误)
                      port="4000"	#传入数据的侦听端口,接收器会自动绑定到范围内的空闲端口 port <= bindPort < port+autoBind
                      autoBind="100"	#每隔多久自动绑定一次套接字,默认值为100
                      selectorTimeout="5000"	#中轮询超时的值(以毫秒为单位),挑选超时时间,当前主机没有合适的IP地址被自动绑定,如果超过5000毫秒后,就放弃并失败退出
                      maxThreads="6"/>	#接收器启动时要创建的最小线程数,一个线程对其他主机信息,一个线程对应一台主机成员,这样可以达到并发接收session的效果,N-1,默认6个也够用

            <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">	#Sender 发送器,向别人发送session,多线程池模式并行发送机制,通道发送器组件负责通过网络传递传出的集群消息
              <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>	#不是必需的,但鼓励使用,因为您可以在此处为传出消息设置所有套接字选项,意味着我们可以同时(并行)向多个目的地发送一条消息
            </Sender>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>	#Interceptor 解析器,解析用户,信道,通信报文,重新的解析器,通信过程有没有发生过TCP传输错误,消息完整性校验;(Apache Tribes 支持拦截器架构来拦截消息和成员资格通知。这种架构允许逻辑解耦,并为一些非常有用的功能添加开辟了道路);TcpFailureDetector - 通过 TCP 验证崩溃的成员,若多播数据包被丢弃,这个拦截器可以防止误报,即使节点仍然处于活动状态并且正在运行,它也被标记为崩溃。
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>	#MessageDispatchInterceptor - 将消息分派到线程(线程池)以异步发送消息
          </Channel>

          <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"	#Valve 过滤器,只复制与复制相关的session;ReplicationValve将在一个 HTTP 请求结束通知集群,使得群集可以作出决定是否有数据要复制或没有
                 filter=""/>
          <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>	#JvmRouteBinderValve将替换jvmWorker会话 Id 中的 属性,以使未来的请求坚持该节点,jvm如果前端调度器试图绑定Engine JVM ROUTE的时候,此处有效,了解即可

          <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"	#Deployer 部署器,比如说有3个节点,每一个节点部署完成,自动传输到其他节点上,但建议不要开启这个功能,因为,一般是需要做灰度部署的时间,自动部署会起反效果的(Farm War Deployer 可以在集群中的其他节点上部署和取消部署 Web 应用程序)
                    tempDir="/tmp/war-temp/"
                    deployDir="/tmp/war-deploy/"
                    watchDir="/tmp/war-listen/"
                    watchEnabled="false"/>

          <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>	#ClusterLitener 集群侦听器,集群资源变动(使用 DeltaManager 时,消息由 Cluster 对象接收并通过此侦听器传播到管理器)
        </Cluster>

应用访问目录

vim /data/myapp/WEB-INF/web.xml
<distributable/>	#在<web-app ..>下方添加

启动集群后,查看tomcat日志

集群监听端口是否开启,是否收到其他集群中其他的组播心跳信息

cat tomcat/logs/catalina.YYYY-MM-DD.log
INFO [main] org.apache.catalina.tribes.transport.ReceiverBase.bind Receiver Server Socket bound to:[/192.168.10.11:4000]

INFO [Membership-MemberAdded.] org.apache.catalina.ha.tcp.SimpleTcpCluster.memberAdded Replication member added:[org.apache.catalina.tribes.membership.Me
mberImpl[tcp://{192, 168, 10, 12}:4000,{192, 168, 10, 12},4000, alive=737369, securePort=-1, UDP Port=-1, id={-105 27 -122 73 -35 -26 79 60 -120 40 -51 -1 73 -85 -39 -86 }, paylo
ad={}, command={}, domain={}]]

检查启动日志相关信息,看下是否有异常

注册
INFO [localhost-startStop-1] org.apache.catalina.ha.session.DeltaManager.startInternal Register manager [localhost#/myapp] to cluster element [Engine] with name [Catalina]
INFO [localhost-startStop-1] org.apache.catalina.ha.session.DeltaManager.startInternal Starting clustering manager at [localhost#/myapp]
INFO [localhost-startStop-1] org.apache.catalina.ha.session.DeltaManager.getAllClusterSessions Manager [localhost#/myapp], requesting session state from [org.apache.catalina.tribes.membership.MemberImpl[tcp://{192, 168, 10, 12}:4000,{192, 168, 10, 12},4000, alive=2407086, securePort=-1, UDP Port=-1, id={-105 27 -122 73 -35 -26 79 60 -120 40 -51 -1 73 -85 -39 -86 }, payload={}, command={}, domain={}]]. This operation will timeout if no session state has been received within [60] seconds.

INFO [main] org.apache.catalina.ha.session.JvmRouteBinderValve.startInternal JvmRouteBinderValve started

客户端访问

1、页面可以看到调度到不同的后端主机
2、session是没有变化的

可使用抓包

[root@tomcatb ~]# tcpdump -i eth0 -nn host 228.0.0.4
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
11:09:57.675297 IP 192.168.10.12.45564 > 228.0.0.4.45564: UDP, length 77
11:09:57.839354 IP 192.168.10.11.45564 > 228.0.0.4.45564: UDP, length 77
11:09:58.175553 IP 192.168.10.12.45564 > 228.0.0.4.45564: UDP, length 77
11:09:58.339546 IP 192.168.10.11.45564 > 228.0.0.4.45564: UDP, length 77

小结

1、yum 安装tomcat
yum install tomcat tomcat-admin-webapps tomcat-docs-webapp tomcat-webapps
2、组播地址建议一组集群使用同一个
3、server使用固定地址,避免影响网络环境
4、集群和后端调度建议网络接口,分开,做分流处理
5、集群建议仅激活自已应用的集群会话,根据实际应用场景
6、很好的测试工具,上千台应用程序压测
https://jmeter.apache.org/

如何使用session server

X 有存储 --> 无存储
Y 有状态 --> 无状态

有状态有存储
有状态无存储
无状态存储
无状态无存储

少数族裔,强大才有人权
规则
只讲道德不讲规则,伪君子遍地
只讲规则不讲道德,基本上都讲道德的

胡适说道德与规则
一个肮脏的国家,如果人人讲规则而不是谈道德,最终会变成一个有人味儿的正常国家,道德自然会逐渐回归;一个干净的国家,如果人人都不讲规则却大谈道德,谈高尚,天天没事儿就谈道德规范,人人大公无私,最终这个国家会堕落成为一个伪君子遍布的肮脏国家。

提供自己的用户体验(沟通,理解别人的意图,协助事情做好>技术能力),
越到大公司越是如此
不要给别人添麻烦,行自己的自由之事

posted @ 2021-09-08 10:42  Final233  阅读(148)  评论(0编辑  收藏  举报