Tomcat实现会话保持

xiaoxiao2025-11-14  3

Tomcat会话保持的几种方式

利用Nginx和Apache反向代理时使用源地址hash算法,将相同源地址的请求发送到相同的一台后端Tomcat服务器利用Tomcat自带的集群工具实现会话绑定,这个方式会让每个Tomcat主机把自己的会话信息共享到其他Tomcat主机。不宜过多,4,5个节点就已经很大了。将会话信息保存到Memcached,当用户访问的时候,会把会话信息保存到一个非关系型数据库Memcached中,当再次访问的时候,Tomcat会到数据库找会话记录,实现会话保持。

这里主要介绍下后面两种方式。

环境准备

ip角色安装的软件192.168.253.128TomcatATomcat192.168.253.158TomcatBTomcat192.168.253.158Nginx反代Nginx

TomcatA的测试页面

<%@ page language="java" %> <html> <head><title>TomcatA</title></head> <body> <h1><font color="red">TomcatA</font></h1> <table align="centre" border="1"> <tr> <td>Session ID</td> <% session.setAttribute("TomcatA","TomcatA"); %> <td><%= session.getId() %></td> </tr> <tr> <td>Created on</td> <td><%= session.getCreationTime() %></td> </tr> </table> </body> </html>

TomcatB测试页面

<%@ page language="java" %> <html> <head><title>TomcatB</title></head> <body> <h1><font color="red">TomcatB</font></h1> <table align="centre" border="1"> <tr> <td>Session ID</td> <% session.setAttribute("TomcatB","TomcatB"); %> <td><%= session.getId() %></td> </tr> <tr> <td>Created on</td> <td><%= session.getCreationTime() %></td> </tr> </table> </body> </html>

访问两个Tomcat节点初始页,出现下图则成功。其中Session ID就是我们的会话ID,如果实现了同一个主机访问得到相同的Session ID则可以认为会话绑定成功。

Nginx反向代理配置文件

[root@localhost ~]# cat /etc/nginx/nginx.conf user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; include /etc/nginx/conf.d/*.conf; upstream tomcat { server 192.168.253.128:8080 weight=1; server 192.168.253.158:8080 weight=1; } server { listen 80 default_server; location / { proxy_pass http://tomcat ; } } }

这里的设置的算法是轮询,权重是1比1

Tomcat Clustering

第一步:修改配置文件server.xml

将下面这段配置添加到每个节点的主配置文件server.xml的 或 组件中

<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="ip" #这里的ip是集群内部通信监听的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>

上面配置的注释

<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"> #channel定义信道 <Membership className="org.apache.catalina.tribes.membership.McastService" address="228.0.0.4" #多播地址通信 port="45564" #多播地址使用的端口,监听再这个端口上的就是同一个集群成员 frequency="500" #每隔0.5s发心跳探测 dropTime="3000"/> #3s没收到心跳探测认为他down了 <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" #接受信息,java内部的一个异步处理逻辑 address="ip" #这里的ip是集群内部通信监听的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>

第二步:配置webapps

在对应的站点目录下,创建WEB-INF/web.xml文件,添加元素; 因为是测试所以比较简单直接复制全局的web.xml,然后再里面添加元素就好了

mkdir /data/test/WEB-INF cp /usr/local/tomcat/conf/web.xml /data/test/WEB-INF/ #复制默认的web.xml到对应的站点目录下

/data/test/WEB-INF/web.xml 中添加下面一行

<distributable/>

两台tomcat节点重启一下tomcat

catalina.sh stop catalina.sh start

可以看到Session ID没变,所以实现了会话保持。

将Session保存在Memcached中

原理:Tomcat会将会话信息保存在Memcached中,当有用户访问时,就可以直接在Memcached中找会话信息。不用基于前端的负载均衡器绑定ip,也不需要tomcat集群互相复制会话信息。 项目地址:https://github.com/magro/memcached-session-manager 项目文档:https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration

第一步:下载memcached-session-manager会话管理工具

下载如下jar文件至各tomcat节点的tomcat安装目录下的lib目录中 其中的${version}要换成你所需要的版本号,tc${6,7,8}要换成与tomcat版本相同的版本号。

memcached-session-manager-${version}.jar memcached-session-manager-tc${6,7,8}-${version}.jar spymemcached-${version}.jar

这里节点是tomcat8.5,具体版本为

memcached-session-manager-1.9.6.jar #下载地址 http://repo1.maven.org/maven2/de/javakaffee/msm/memcached-session-manager/1.9.6/ memcached-session-manager-tc8-1.9.6.jar #下载地址http://repo1.maven.org/maven2/de/javakaffee/msm/memcached-session-manager-tc8/1.9.6/ spymemcached-2.12.2 #下载地址 http://repo1.maven.org/maven2/net/spy/spymemcached/2.12.2/

将这些文件下载到tomcat的lib目录下

第二步:添加序列化序列化工具javolution-serializer

这里的序列化工具有许多种

kryo-serializer: msm-kryo-serializer, kryo-serializers-0.34+, kryo-3.x, minlog, reflectasm, asm-5.x, objenesis-2.xjavolution-serializer: msm-javolution-serializer, javolution-5.4.3.1xstream-serializer: msm-xstream-serializer, xstream, xmlpull, xpp3_minflexjson-serializer: msm-flexjson-serializer, flexjson

这次使用的序列化工具是javolution-serializer,具体版本如下

msm-javolution-serializer #下载地址 http://repo1.maven.org/maven2/de/javakaffee/msm/msm-javolution-serializer/1.9.6/ javolution-5.4.3.1 #下载地址 http://www.java2s.com/Code/Jar/j/Downloadjavolution5431jar.htm

将这些文件下载到tomcat的lib目录下

第三步:修改配置文件

分别在两个tomcat上的某host上定义一个用于测试的context容器,并在其中创建一个会话管理器,如下所示:

<Context path="" docBase="/data/test" reloadable="true" > <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="n1:192.168.253.128:11211,n2:192.168.253.158:11211" failoverNodes="n1" requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$" transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory" /> </Context>

第四步:安装Memcached

在两个tomcat节点安装Memcached并启动

yum install memcached -y systemctl start memcached

第五步:重启Tomcat并测试

catalina.sh stop catalina.sh start

在刷新一次

这时候可以看到使用的是n2这个主机的Memcached,这时候我们down了n2(192.168.253.158)的Memcached

可以看到Session ID没变,但是后面变成了n1节点,证明了即使n2宕了,n1也能接管服务

转载请注明原文地址: https://www.6miu.com/read-5039643.html

最新回复(0)