zl程序教程

您现在的位置是:首页 >  Java

当前栏目

Tomcat的Session复制集群

2023-03-15 23:26:25 时间

配置说明

Cluster 集群配置
Manager 会话管理器配置
Channel 信道配置
    Membership 成员判定。使用什么多播地址、端口多少、间隔时长ms、超时时长ms。同一个多播地址和端口认为同属一个组。使用时修改这个多播地址,以防冲突
    Receiver 接收器,多线程接收多个其他节点的心跳、会话信息。默认会从4000到4100依次尝试可用端口
    address="auto",auto可能绑定到127.0.0.1上,所以一定要改为可以用的IP上去
    Sender 多线程发送器,内部使用了tcp连接池。
    Interceptor 拦截器
Valve
    ReplicationValve 检测哪些请求需要检测Session,Session数据是否有了变化,需要启动复制过程
ClusterListener
    ClusterSessionListener 集群session侦听器

使用

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>

添加到

<Engine>

所有虚拟主机都可以启用Session复制

添加到

<Host>

该虚拟主机可以启用Session复制

最后,在应用程序内部启用了才可以使用

5.1 配置nginx调度器使用轮询机制

[19:57:00 root@nginx ~]#vim /etc/nginx/nginx.conf
...
    upstream tomcat-server {
    #ip_hash;                  
    #hash $cookie_JSESSIONID;
    server t1.tomcat.org:8080;
    server t2.tomcat.org:8080;
    }
...  

5.2 在两台后端Tomcat主机上修改server.xml配置

复制集群的配置可以配置在Host中, 针对某个虚拟主机, 也可配置在Engine中, 针对所有的虚拟主机

Receiver的address要修改为本机可对外的ip地址

5.2.1 修改t1主机的server.xml文件

     <Host name="t1.tomcat.org"  appBase="/data/webapps"
            unpackWARs="true" autoDeploy="true">
        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->
        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
<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="230.100.100.8"
                port="45564"                  #45564/UDP
                frequency="500"
                dropTime="3000"/>
    <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
              address="10.0.0.82"   #此项建议修改为当前主机的IP
              port="4000"
              autoBind="100"
              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.MessageDispatchInterceptor"/>
  </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.ClusterSessionListener"/>
</Cluster>
      </Host>

5.2.2 修改t2主机的server.xml文件

      <Host name="t2.tomcat.org"  appBase="/data/webapps"
            unpackWARs="true" autoDeploy="true">
        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->
        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
<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="230.100.100.8"
                port="45564"                  #45564/UDP
                frequency="500"
                dropTime="3000"/>
    <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
              address="10.0.0.83"   #此项建议修改为当前主机的IP
              port="4000"
              autoBind="100"
              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.MessageDispatchInterceptor"/>
  </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.ClusterSessionListener"/>
</Cluster>
      </Host>

5.3 修改每个虚拟主机的web.xml文件, 启用分布式

5.3.1 修改t1主机的web.xml文件

[20:51:13 root@t1 ~]#cp -a /usr/local/tomcat/webapps/ROOT/WEB-INF/ /data/webapps/ROOT
[20:54:55 root@t1 ~]#tree /data/webapps/ROOT/
/data/webapps/ROOT/
├── index.jsp
└── WEB-INF
    └── web.xml
1 directory, 2 files
  <description>
     Welcome to Tomcat
  </description>
<distributable/>                                                                                                                                                                    
</web-app>
[20:56:26 root@t1 ~]#systemctl restart tomcat
[20:56:26 root@t1 ~]#ss -ntl
State                  Recv-Q                  Send-Q                                        Local Address:Port                                   Peer Address:Port                 
LISTEN                 0                       128                                                 0.0.0.0:22                                          0.0.0.0:*                    
LISTEN                 0                       128                                                    [::]:22                                             [::]:*                    
LISTEN                 0                       50                                       [::ffff:10.0.0.82]:4000           # 开启4000端口                                   *:*                    
LISTEN                 0                       1                                        [::ffff:127.0.0.1]:8005                                              *:*                    
LISTEN                 0                       100                                                       *:8080                                              *:*  

5.3.2 修改t2主机的web.xml文件

[20:51:13 root@t2 ~]#cp -a /usr/local/tomcat/webapps/ROOT/WEB-INF/ /data/webapps/ROOT
[20:54:55 root@t2 ~]#tree /data/webapps/ROOT/
/data/webapps/ROOT/
├── index.jsp
└── WEB-INF
    └── web.xml
1 directory, 2 files
  <description>
     Welcome to Tomcat
  </description>
<distributable/>                                                                                                                                                                    
</web-app>
[20:56:26 root@t2 ~]#systemctl restart tomcat
[21:02:10 root@t2 ~]#ss -ntl
State                  Recv-Q                  Send-Q                                        Local Address:Port                                   Peer Address:Port                 
LISTEN                 0                       128                                                 0.0.0.0:22                                          0.0.0.0:*                    
LISTEN                 0                       1                                        [::ffff:127.0.0.1]:8005                                              *:*                    
LISTEN                 0                       100                                                       *:8080                                              *:*                    
LISTEN                 0                       128                                                    [::]:22                                             [::]:*                    
LISTEN                 0                       50                                       [::ffff:10.0.0.83]:4000                                              *:* 

5.3 查看t1和t2上的复制日志

# t1
23-Mar-2021 21:02:08.474 INFO [Membership-MemberAdded.] org.apache.catalina.ha.tcp.SimpleTcpCluster.memberAdded Replication member added:[org.apache.catalina.tribes.membership.MemberImpl[tcp://{10, 0, 0, 83}:4000,{10, 0, 0, 83},4000, alive=1017, securePort=-1, UDP Port=-1, id={18 -28 -37 52 10 94 74 -58 -107 -83 1 65 -69 76 -102 8 }, payload={}, command={}, domain={}]]
# t2
talina.tribes.membership.MemberImpl[tcp://{10, 0, 0, 82}:4000,{10, 0, 0, 82},4000, alive=352758, securePort=-1, UDP Port=-1, id={113 -35 -13 18 -28 116 68 87 -66 127 -82 -58 98 -56 -114 -124 }, payload={}, command={}, domain={}]]. This operation will timeout if no session state has been received within [60] seconds.

5.4 访问测试

重启全部Tomcat, 通过负载均衡调度到不同的节点, 返回的SessionID相同, 但是后端的主机是轮询的

图片.png

图片.png

5.5 故障模拟

  1. 先访问一次, 调度到10.0.0.83, 并获取SessionID
  2. 关闭10.0.0.83上的Tomcat
[21:09:46 root@t2 ~]#systemctl stop tomcat
  1. 在10.0.0187利用curl携带SessionID进行访问, 可以看到, 携带了10.0.0.83产生的SessionID后, 每次访问都是用户的固定的SessionID, 说明10.0.0.82上复制了10.0.0.83的SessionID
[21:10:43 root@client ~]#curl -b 'JSESSIONID=D5FB8FDA21F1081E705C41A52E613613' www.tomcat.org/index.jsp
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>tomcat test</title>
</head>
<body>
<div>On tomcat-server</div>
<div>10.0.0.82:8080</div>
<div>SessionID = <span style="color:blue">D5FB8FDA21F1081E705C41A52E613613</span></div>                                                                        
Tue Mar 23 21:10:48 CST 2021
</body>
</html>
[21:10:47 root@client ~]#curl -b 'JSESSIONID=D5FB8FDA21F1081E705C41A52E613613' www.tomcat.org/index.jsp
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>tomcat test</title>
</head>
<body>
<div>On tomcat-server</div>
<div>10.0.0.82:8080</div>
<div>SessionID = <span style="color:blue">D5FB8FDA21F1081E705C41A52E613613</span></div>                                                                        
Tue Mar 23 21:10:49 CST 2021
</body>
</html>