基于Memcached/Redis实现Tomcat8.x的Session共享
为什么要共享session?
我们使用单台Tomcat的时候,不会有共享sesssion的问题,只要使用Tomcat的默认配置,session即可存储在Tomcat上。

但是随着业务的扩大,需要增加节点构成Tomcat集群,分布式带来了更大规模并发请求的优势,但是也遇到一个问题,每个Tomcat只存储来访问自己的请求产生的session。
如果Tomcat-A已经为客户端C创建了会话session,那么Tomcat-B并不知道客户端已与集群中的Tomcat-A产生了会话,在访问时就会为C再创建一份session,就会造成数据丢失。
若是基于session的验证会话权限的接口(如用户登录认证后才可访问的数据接口),就会导致在访问集群中不同节点时重复认证,session的不共享导致原会话在Tomcat集群中无法工作。

若Tomcat集群的任一节点都能访问的公共session存取区,就可以解决问题了,我们可以使用Memcached或Redis来做这个session公共存取区,这样就能统一管理会话了。

一、 Tomcat篇
1.1 配置JDK
官网下载 https://www.oracle.com/java/technologies/downloads/#java8
[root@node01 ~]# tar zxf jdk-8u131-linux-x64.tar.gz
[root@node01 ~]# mv jdk1.8.0_131/ /usr/local/jdk
[root@node01 ~]# cat /etc/profile.d/java.sh
JAVA_HOME=/usr/local/jdk
JAVA_BIN=/usr/local/jdk/bin
JRE_HOME=/usr/local/jdk/jre
PATH=$PATH:/usr/local/jdk/bin:/usr/local/jdk/jre/bin
CLASSPATH=/usr/local/jdk/jre/lib:/usr/local/jdk/lib:/usr/local/jdk/jre/lib/charsets.jar
[root@node01 ~]# . /etc/profile.d/java.sh
[root@node01 ~]# java -version
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
或者使用yum安装jdk;
[root@node01 ~]# yum install -y java-1.8.0-openjdk
[root@node01 ~]# java -version
openjdk version "1.8.0_312"
OpenJDK Runtime Environment (build 1.8.0_312-b07)
OpenJDK 64-Bit Server VM (build 25.312-b07, mixed mode)
1.2 获取tomcat
Tomcat官网 https://tomcat.apache.org;
[root@node01 ~]# tar xf apache-tomcat-8.5.76.tar.gz
[root@node01 ~]# mv apache-tomcat-8.5.76 /opt/tomcat8
创建jsp测试页;
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<body>
<table align="left" border="1">
<tr>
<td>Server URL</td>
<td><%="http://"+request.getLocalAddr()+":"+request.getLocalPort()%></td>
</tr>
<tr>
<td>Session ID</td>
<td><%=session.getId()%></td>
</tr>
<tr>
<td>created on</td>
<td><%=session.getCreationTime()%></td>
</tr>
</table>
</body>
</html>
配置systemctl;
[root@node01 ~]# cat /usr/lib/systemd/system/tomcat.service
[Unit]
Description=tomcat
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
ExecStart=/opt/tomcat8/bin/startup.sh
ExecStop=/opt/tomcat8/bin/shutdown.sh
[Install]
WantedBy=multi-user.target
预览效果如下图,

二、Nginx篇
2.1 安装Nginx
[root@node01 ~]# yum install -y pcre pcre-devel openssl openssl-devel zlib zlib-devel
[root@node01 ~]# yum install -y nginx
[root@node01 ~]# systemctl start nginx && systemctl enable nginx
2.2 Nginx代理Tomcat
[root@node01 ~]# vim /etc/nginx/nginx.conf
http模块配置upstream;
upstream tomcat {
server 10.100.1.121:8080;
server 10.100.1.122:8080;
server 10.100.1.123:8080;
}
server模块配置location;
location / {
proxy_pass http://tomcat;
proxy_set_header Host $Proxy_Host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
重载nginx服务;
[root@node01 ~]# nginx -s reload
2.3 访问测试
访问nginx的请求会按权重轮流分发至各tomcat,但sessionID会随着页面刷新而变动。
三、Session篇
3.1 Memcached实现Session共享
安装memcached服务;
[root@node01 ~]# yum install -y memcached
[root@node01 ~]# systemctl start memcached && systemctl enable memcached
memcached-session-manager on github:
https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration#decide-which-serialization-strategy-to-use


注意版本要求,以下是整合的jar包,移至tomcat/lib目录下;
下载地址:https://files.cnblogs.com/files/blogs/719684/memcached-session-manager.zip?t=1647972489
[root@node01 ~]# ll *.jar
-rw-r--r-- 1 root root 53259 Dec 23 2016 asm-5.2.jar
-rw-r--r-- 1 root root 285211 Jul 27 2015 kryo-3.0.3.jar
-rw-r--r-- 1 root root 85217 May 26 2016 kryo-serializers-0.38.jar
-rw-r--r-- 1 root root 167266 Mar 19 2018 memcached-session-manager-2.3.0.jar
-rw-r--r-- 1 root root 10822 Mar 19 2018 memcached-session-manager-tc8-2.3.0.jar
-rw-r--r-- 1 root root 5923 Dec 29 2018 minlog-1.3.1.jar
-rw-r--r-- 1 root root 38268 Mar 19 2018 msm-kryo-serializer-2.3.0.jar
-rw-r--r-- 1 root root 54393 Jan 13 2017 objenesis-2.5.jar
-rw-r--r-- 1 root root 72276 Dec 29 2018 reflectasm-1.11.8.jar
-rw-r--r-- 1 root root 473774 May 1 2017 spymemcached-2.12.3.jar
[root@node01 ~]# mv *.jar /opt/tomcat8/lib/
配置tomcat/conf/context.xml;
[root@node01 ~]# vim /opt/tomcat8/conf/context.xml
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:10.100.1.121:11211,n2:10.100.1.122:11211,n3:10.100.1.123:11211"
lockingMode="auto"
sticky="false"
sessionBackupAsync="false"
sessionBackupTimeout= "1000"
copyCollectionsForSerialization="true"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
重启tomcat服务,继续测试,发现session已实现共享;

n3表示session处于node03节点的memcached服务上;
停止node03节点的memcached服务,session会话转移到n1的memcached上了,sessionID依然没变;

至此,memcached已实现tomcat的session共享。
3.2 Redis实现Session共享
https://github.com/cc-chen/tomcat8.5-redis-session-manager
未完,待续!

浙公网安备 33010602011771号