首页 > 其他分享 >Tomcat 入门实战(4)--Tomcat 集群 Session 复制

Tomcat 入门实战(4)--Tomcat 集群 Session 复制

时间:2023-04-02 10:24:37浏览次数:47  
标签:xml Tomcat -- server Session 集群 复制 节点

本文主要介绍在 Tomcat 集群中如何进行 Session 复制,文中所使用到的软件版本:Centos 7.9.2009、Java 1.8.0_321、Tomcat 8.5.87。

1、快速配置

取消 conf/server.xml 文件中的以下注释来启用集群:

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

使用上述配置将启用 all-to-all 会话复制,它使用 DeltaManager 进行会话增量复制。all-to-all 意味着每个会话都将被复制到群集中的所有其他节点。这对于较小的集群非常有效,但不建议在大型集群(超过4个节点左右)中使用它。此外,当使用 DeltaManage r时,Tomcat 将会话复制到所有节点,甚至是没有部署该应用程序的节点。
为了解决这些问题,您将需要使用 BackupManager。BackupManager 仅将会话数据复制到一个备份节点,并且仅复制到已部署该应用程序的节点。一旦您使用 DeltaManage r运行了一个简单的集群,您可能希望随着增加集群中节点的数量而迁移到 BackupManager。

上述配置对应的详细默认配置如下:

<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="228.0.0.4"
                port="45564"
                frequency="500"
                dropTime="3000"/>
    <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
              address="auto"
              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>

以下是一些重要的默认值:
1、组播地址为 228.0.0.4
2、组播端口为 45564(端口和地址一起确定集群成员身份)
3、广播的 IP 是 java.net.InetAddress.getLocalHost().getHostAddress()(确保不要广播127.0.0.1,这是一个常见错误)
4、用于监听复制消息的 TCP 端口是在 4000-4100 范围内第一个可用的服务器套接字
5、侦听器配置为 ClusterSessionListener
6、配置了两个拦截器 TcpFailureDetector 和 MessageDispatchInterceptor

2、Session 复制实现步骤

1、所有会话属性必须实现 java.io.Serializable 接口。
2、在 conf/server.xml 文件中取消注释 Cluster 元素。
3、如果您定义了自定义集群阀门,请确保在 conf/server.xml 文件的 Cluster 元素下也定义了 ReplicationValve。
4、如果 Tomcat 实例在同一台机器上运行,确保每个实例的 Receiver.port 属性是唯一的。在大多数情况下,Tomcat 可以通过自动检测 4000-4100 范围内可用端口来解决此问题。
5、确保应用的 web.xml 具有 <distributable/> 元素。
6、如果使用 mod_jk,请确保在 Engine(<Engine name="Catalina" jvmRoute="node01">) 中设置 jvmRoute 属性,并且 jvmRoute 属性值与 workers.properties 中的 worker 名称匹配。
7、确保所有节点具有相同的时间并与 NTP 服务同步.
8、确保负载均衡器配置为粘性会话模式。

3、实际操作

3.1、规划

IP 端口 用途
10.49.196.10 8080 Tomcat1
10.49.196.11 8080 Tomcat2
10.49.196.13 8080 反向代理(Nginx)

3.2、修改 server.xml

取消 Tomcat 中 conf/server.xml 文件的以下注释:

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

3.3、添加 <distributable/>

这里直接使用 Tomcat 自带的应用 ROOT 做测试,在 webapps/ROOT/WEB-INF/web.xml 文件中增加 <distributable/>:

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  version="3.1"
  metadata-complete="true">

  <display-name>Welcome to Tomcat</display-name>
  <description>
     Welcome to Tomcat
  </description>
  <distributable/>
</web-app>

3.4、添加测试页面

新增 webapps/ROOT/index2.jsp 文件:

<body>
SessionID:<%=session.getId()%>
<br>
SessionIP:<%=request.getLocalAddr()%>
<br>
SessionPort:<%=request.getLocalPort()%>
</body>

3.5、配置反向代理

Nginx 的配置如下:

upstream tomcat {
  server 10.49.196.30:8080;
  server 10.49.196.31:8080;
}

server {
  listen 7070;
  server_name  localhost;
  
  location / {
    proxy_pass  http://tomcat;
  }
}

3.6、测试

启动两个 Tomcat 及 Nginx,访问代理页面:

 

多次访问代理页面,可以看到 IP 不停的变化,但 SessionID 不变,说明 Session 复制有效。

 

 

参考:https://tomcat.apache.org/tomcat-8.5-doc/cluster-howto.html

标签:xml,Tomcat,--,server,Session,集群,复制,节点
From: https://www.cnblogs.com/wuyongyin/p/17260877.html

相关文章

  • java面向对象编程
    面向对象编程java的核心思想就是OOP面向过程&面向对象面向过程:步骤清晰简单,第一步做什么,第二步做什么···适合处理较为简单的问题面向对象:物理类聚,分类的思维模式,思考问题首先解决问题需要哪些分类,然后对这些分类进行单独思考,最后对某个分类下的细节进行面向过......
  • 用户注册,用到局部钩子校验和全局钩子检验
    1.路由分发 2.局部钩子对字段单独校验和re_password校验不入库操作  3.views  4.models ......
  • 咬咬龟对前缀和的反对
    咬咬龟对前缀和的反对在计算机科学中,前缀和(PrefixSum)是一种常见的算法技术,用于高效地处理数组或序列中某一区间内元素的和。然而,在最近的一次直播中,国内知名主播咬咬龟表达了他对前缀和算法的反对意见,引发了广泛的讨论和争议。咬咬龟指出,前缀和算法虽然在某些情况下可以提高算......
  • kafka(java客户端)生产者消费者不能连接虚拟机kafka
    报错如下:...:localhost:9092...java.net.ConnectException:Connectionrefused:nofurtherinformationatsun.nio.ch.SocketChannelImpl.checkConnect(NativeMethod)atsun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:739)atorg.apac......
  • java面向对象编程-方法回顾
    方法回顾和加深方法的定义修饰符返回类型方法名:注意规范,见名知意参数列表:参数类型参数名异常抛出:后面讲解  方法的调用静态方法非静态方法形参和实参值传递和引用传递this关键字    ......
  • [I]CF With AT
    EducationalCodeforcesRound127(RatedforDiv.2)A显然,长度\(2\)和\(3\)能拼出任意长度字符串,所以无解情况考虑有没有单独的长度为\(1\)的即可。/*byL1rs1ngzN1sLyr*/#include<bits/stdc++.h>constintAI=1e3+9;constintKI=1e6+2;constintCI=1e7+3;i......
  • 4404. X 进制减法
    原题链接代码#include<iostream>#include<algorithm>usingnamespacestd;constintN=100010;constintmod=1000000007;inta[N],b[N];//总结:记得开longlong/*题目中的65是指:1*1+2*2+3*2*10=65;两数相减取最小进制位,每一位的最小进制位为a和b......
  • CF594A Warrior and Archer 题解
    由于本人在思索了很久后才把本题思路打通,所以为了帮助像我一样没有非常理解解法的人,我打算再将解法非常详细地叙述一遍,如果您无法理解解法,请跟着我再一步步将题目捋顺。Step.1解题意题目要求其实很好理解,共给出\(n\)个点的位置,A,B两个人轮流取点,A要求最后剩下的两个点尽量近,B......
  • 洛谷 P8918 『MdOI R5』Jump 题解
    题目传送门这一题其实很简单,只是要想到正确方法我一开始用了奇怪的搜索①无解的情况:看上去很离奇,实际上略加思索就会发现,如果输入\(n\)为偶数,那么就铁定无解。证明过程如下:令\(n\bmod{2}=0\),人距离\(n\)点的距离为\(dis\),则当走出第一步(步长为\(1\))时,有:\[dis=\midn......
  • 面向对象
    一、面向对象基本概念1、面向对象编程:oop2、面向过程:根据需求将某些独立功能封装为一个又一个函数,最后完成的代码,就是顺序地调用不同函数3、面向对象:相比较函数,面向对象就是更大的封装,根据职责在一个对象中封装多个方法,根据职责确定不同对象,在对象内部封装不同方法......