Tomcat集群session共享问题
j集群环境下多台Tomcat之间并不共享session存储空间,当请求切换到不同tomcat服务时导致session数据丢失的问题。
思路分析:
每个tomcat中都有一份属于自己的session,假设用户第一次访问第一台tomcat,并且把自己的信息存放到第一台服务器的session中,但是第二次这个用户访问到了第二台tomcat,那么在第二台服务器上,肯定没有第一台服务器存放的session,所以此时 整个登录拦截功能就会出现问题,我们能如何解决这个问题呢?
常见Session共享方案分析
Session共享方案应满足:数据共享、内存存储、key/Value结构
一 使用nginx的ip_hash
使用ip绑定ip_hash算法时,用户的请求都会绑在同一个节点服务器上,这样的设置会导致一台或多台服务器过载无法提供服务,而后端正常的服务器无法提供服务,当绑定的服务器挂了,用户只能重启浏览器后才能重新访问,这样用户体验度极差,除了特殊需要,不建议使用这种机制实现session共享
二 基于服务端的session共享
1 基于Tomcat提供的session复制
该方案就是说每个tomcat上都有不同的session,但是每当任意一台服务器的session修改时,都会同步给其他的Tomcat服务器的session,这样的话,就可以实现session的共享了。但是这种方案具有以下问题:
1、集群内每台服务器中都有完整的一份session数据,浪费内存空间(当Tomcat多的时候)。
2、当Tomcat多的时候,session在拷贝同步到集群内其他机器上时,可能会出现延迟(占用内网宽带)。拷贝期间有用户访问,仍然无法登录
2 基于memcached/file来实现
本处不多做介绍,感兴趣的同学可以自行查阅资料。
3 基于jcoleman的redis解决方案
此方案仅支持tomcat6和7,如果要支持tomcat8或9需要修改代码,然后打包部署,非常麻烦。不建议使用。故此处不再赘述。附参考资料以便自行了解学习
参考资料:
4 基于Redisson的redis解决方案
4.1 环境准备
IP | 软件 | 软件版本 |
127.0.0.1 | Nginx | nginx-1.24.0 |
127.0.0.1:8080 | Tomcat | apache-tomcat-9.0.74-1 |
127.0.0.1:8081 | Tomcat | apache-tomcat-9.0.74-2 |
127.0.0.1:6379 | Redis | Redis-x64-5.0.14.1 |
4.2 nginx+tomcat+redis部署过程
4.2.1 Redis安装部署
1 下载安装
1)访问https://github.com/tporadowski/redis/releases地址,下载Redis-x64-5.0.14.1.zip
2)解压Redis-x64-5.0.14.1.zip文件,点击执行redis-server.exe,如图:
注意:如需设置访问密码,请编辑redis.windows.conf文件。如图:
4.2.2 Tomcat安装部署
下载安装
1)访问https://tomcat.apache.org/download-90.cgi地址,下载apache-tomcat-9.0.74.zip文件
2)解压apache-tomcat-9.0.74.zip文件,如图:
3)Tomcat端口修改
apache-tomcat-9.0.74-1端口保持原值不变,修改apache-tomcat-9.0.74-2的端口,如下图:
apache-tomcat-9.0.74-2/conf/server.xml
4)修改 TOMCAT_BASE/webapps/ROOT/index.jsp,添加:
<table align="center" border="1"> <tr> <td>cluster-desc</td> <!-- 分别修改描述 --> <td>This is the first tomcat</td> <td>This is the second tomcat</td> </tr> <tr> <td>SessionID</td> <td><%= request.getSession().getId() %></td> </tr> <tr> <td>SessionCreatedTime</td> <td><%= request.getSession().getCreationTime() %></td> </tr> <tr> <td>ServerName</td> <td><%=request.getServerName()%></td> </tr> <tr> <td>SessionPort</td> <td><%=request.getServerPort()%></td> </tr> </table>
5)apache-tomcat-9.0.74-1、apache-tomcat-9.0.74-1访问验证
分别访问http://127.0.0.1:8080/,http://127.0.0.1:8081/ 链接,如下图(sessionId都是不一样的):
4.2.3 Nginx安装部署
下载安装
1)访问http://nginx.org/en/download.html链接,下载nginx-1.24.0.zip文件
2)解压nginx-1.24.0.zip文件,如图
3)nginx负载均衡配置
nginx-1.24.0/conf/nginx.conf
upstream ha-balance { server 127.0.0.1:8080 weight=1; server 127.0.0.1:8081 weight=1; } location = / { proxy_pass http://ha-balance; }
4)测试验证,访问:http://127.0.0.1 发现每次的sessionId都是不一样的
4.2.4 配置tomcat session共享
4.2.4.1、Add session manager
1)Add shared redisson instance produced by JndiRedissonFactory
into tomcat/conf/server.xml
in GlobalNamingResources
tag area:
<GlobalNamingResources> <Resource name="bean/redisson" auth="Container" factory="org.redisson.JndiRedissonFactory" configPath="${catalina.base}/conf/redisson.yaml" closeMethod="shutdown"/> </GlobalNamingResources>
2)Add JndiRedissonSessionManager
with resource link to redisson instance into tomcat/conf/context.xml
<ResourceLink name="bean/redisson" global="bean/redisson" type="org.redisson.api.RedissonClient" /> <Manager className="org.redisson.tomcat.JndiRedissonSessionManager" readMode="REDIS" jndiName="bean/redisson" />
3)新增redisson配置文件 tomcat/conf/redisson.yaml
更多配置可以参考
singleServerConfig: idleConnectionTimeout: 10000 connectTimeout: 10000 timeout: 3000 retryAttempts: 3 retryInterval: 1500 password: null subscriptionsPerConnection: 5 clientName: null address: "redis://127.0.0.1:6379" subscriptionConnectionMinimumIdleSize: 1 subscriptionConnectionPoolSize: 50 connectionMinimumIdleSize: 24 connectionPoolSize: 64 database: 0 dnsMonitoringInterval: 5000 threads: 16 nettyThreads: 32 codec: !<org.redisson.codec.MarshallingCodec> {} transportMode: "NIO"
4.2.4.2 下载并复制2个Jar包到Tomcat Lib目录下
Tomcat 7.x - redisson-tomcat-7-3.21.0.jar
Tomcat 8.x - redisson-tomcat-8-3.21.0.jar
Tomcat 9.x - redisson-tomcat-9-3.21.0.jar
Tomcat 10.x - redisson-tomcat-10-3.21.0.jar
4.2.5 session共享测试验证
重启tomcat,访问:http://127.0.0.1/ 发现每次的sessionId都是一样的
参考资料:
https://github.com/redisson/redisson/tree/master/redisson-tomcat
https://github.com/redisson/redisson/wiki/2.-Configuration
Tomcat+redis+Redisson实现session共享http://chanpinxue.cn/archives/5694.htmlhttps://blog.csdn.net/chenyang_wei/article/details/127846656