Tomcat8+Redis集群解决会话共享

瞎  扯

磕磕碰碰一天,百度了好几篇,终于搞定了Session共享的问题。以前只是听说将Session存入第三方来解决Session共享问题,可一直没有亲自动手实现过,还记得以前面试时被一道怎么用Redis解决Session共享问题给怼得老惨,现在再问到,虽然可能还是会被怼,但多多少少能说上几句了。此文纯粹是记录我这一天解决这问题的过程,要想面试打败面试官,多去找找其他博文。

问题起源:服务器端Tomcat集群,负载策略采用的Ip-Hash方式,不存在Session共享问题,后因Jmeter压测,在无权更改测试机为多IP模拟IP欺骗的情况下,将负载策略更改为轮询方式,然后,就有活干了。 

参 考 致 谢

负载策略可参考:https://blog.csdn.net/qq_35119422/article/details/81505732

需要用到Redis Session Manager for Apache Tomcat项目,https://github.com/jcoleman/tomcat-redis-session-manager ,但是官方说的了,暂时不支持tomcat8,上Github上逛了一圈,无私奉献的大神挺多的,因为我项目用到的是tomcat8.5,找了好几个才找到个简单可用的(没有试是否支持其他版本)。

源码我用的这哥们的:https://github.com/cc-chen/tomcat8.5-redis-session-manager.git,万分感谢!

下 载 配 置

省事的朋友们,可跳过源码,所需jar包我打好了,需要的自行下载:

下载地址:https://pan.baidu.com/s/1DuY-S9GHCgvWmTn1DvvvOg

提取码:cg6g

解压后为这三个jar包,

jedis-2.5.2.jar,

commons-pool2-2.2.jar

tomcat8.5-redis-session-manager.jar

将这三个包放在tomcat的lib目录下,然后修改config目录下context.xml文件,新增如下配置(大多数博主通用配置):

<Valve className="com.s.tomcat.redissessions.RedisSessionHandlerValve" />

<Manager className="com.s.tomcat.redissessions.RedisSessionManager"

        host="127.0.0.1"

        port="6379"

        database="0"

        password="123456"     

        maxInactiveInterval="60" />

参数说明:

通用配置

className:tomcat8.5-redis-session-manager.jar中类全路径,有木有发现,与网上其他大多数博客写的名称不一样,是因为该jar包有修改原官网项目包名。

host:redis master Ip地址

port:redis master 端口

password:redis密码

database:数据库下标(redis默认从0到15 16个分区)

maxInactiveInterval:session超时时间,单位min(测试无效,该怎么设置和失效原因后续会说明)

测试方法:

默认Redis主从集群已经配置好,测试结果如下,(由于是本地,所以Tomcat,Redis均为伪集群,也就是IP一样端口不一样)

在各个tomcat/webapp/ROOT 目录下的jsp页面合适位置加上IP:Port-Session Id : <%= request.getSession().getId() %>(我选择的第51行),启动tomcat8086,8087,tomcat启动前保证Redis主从集群运行正常,否则tomcat启动会报错,启动成功后,访问tomcat主页,在同一浏览器输入:127.0.0.1:8086,127.0.0.1:8087,查看页面的sessionId以及reids中sessionId,如果如图所示,恭喜你,成功一半了:

如果redis中存上了sessionId,且两个tocat服务sessionId一样,重复刷新,sessionId不变,验证成功。

然后删除Redis中的sessionId,再次刷新。

此时sessionId变了,但是两个服务的sessionId仍然一样,验证成功。

大多数博客到这就完了,但真的成功了么?NO!

哨兵集群配置

上面配置是大多数博客都写到的配置,不知道大家发现个问题没,上面host配置只有一个地址,既主节点地址。当redis为单机时,或者集群模式为主从模式时,这样配置才好使,因为我们只需配置主节点连接信息就可以了,但主节点宕了,不就崩了么?现在大多数用到redis的服务,为保证其高可用,几乎都会选择哨兵模式或者Redis-Cluster模式吧。那么问题来了,当主节点宕了后,当其他从节点升级为主节点后,节点连接信息变了,那上面的配置是不是得改了?

不用惊讶,因为当初找到的几篇博客都大同小异,没有提到这种场景,官网看了下,奈何全是英文,就自个研究了下源码,这就是传说中的自己坑自己吧!后来也有看到别的博文介绍哨兵集群时tomcat conf.xml的配置,去官网上也看到了相关的配置说明。不过我弄的时候没看到啊,晕!塞翁失马焉知非福,虽然也不知道研究了下源码得到了啥收获。。。。

要了解多个的配置,首先看看源码中怎么读取单个host,port等配置参数的,找找看:

719行,新建JedislPool用到了咱们配置文件里的参数,看看else另一个条件,那个sentinel单词不就是哨兵么,看看里面相关的sentinelMaster,sentinelSet的get、set方法,

sentinelMaster需要传个master,sentinelSet需要传个sentinels,顾名思义,master是主节点名称,sentinels是各个节点的连接信息,抱着试一试的态度,在context.xml配置文件中又加上俩参数。

同样:这里默认Redis集群模式已经更改为哨兵模式且正常运行(Redis哨兵集群这里就不赘述了)。

sentinelMaster="mymaster"

sentinels="127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381"

新增参数说明:

sentinelMaster:master名称

sentinels:哨兵集群时地址配置,IP:port,用英文逗号隔开

然后重启tomcat集群,接下来继续验证:验证方式和上面一样,当上面两个步骤验证完后,将当前主节点手动关掉,然后再次刷新浏览器验证,发现sessionId依然有效,至此,已经成功百分之九十了。

过期时间

剩下的百分之十,就是session过期的问题了。在启动tomcat时,会有个警告

说明那个maxInactiveInterval参数配置有点问题。出问题了,那就源码里看看啥情况,找到源码中设置session超时时间的地方,在RedisSessionManager类中,377和545行还有632行,这个时间值都用到的getMaxInactiveInterval()方法,如下

再看看getMaxInactiveInterval()方法

看到这儿似乎明白了,本项目中并不是根据我们的配置文件中参数赋值,这个时间设置的值取的是Tomcat容器的session-timeout 节点(单位min),更改tomcat  conf/web.xml配置,约595行

<session-config>

        <session-timeout>10</session-timeout>

</session-config>

去掉配置文件中的maxInactiveInterval参数,更改web.xml 中session-timeout时间为2分钟,重启Tomcat测试session失效场景,验证成功,至此Tomcat8.5集成Redis 解决Session会话共享问题算是大功告成!

谨记,官方文档很重要!很重要!很重要!仔细看看会少走很多弯路!

以上内容均为个人对别人成果的学习和总结,有理解不到位的地方,还请各路大神指点!

原创不易,看了觉得有帮助的朋友们,记得点个赞哟,谢谢!

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
当将会话管理从 Tomcat 切换到 Spring Session + Redis 时,有几个注意事项: 1. 配置 Redis:确保已正确配置和启动 Redis 服务器。你需要提供 Redis 的主机名、端口号和认证信息(如果有的话)。 2. 添加 Spring SessionRedis 的依赖:在项目的构建文件中,添加 Spring SessionRedis 的依赖。例如,在 Maven 中,你可以添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency> ``` 3. 配置 Spring Session:在 Spring Boot 的配置文件中,添加以下配置来启用 Spring Session 和指定 Redis 的连接信息: ```properties # 启用 Spring Session spring.session.store-type=redis # Redis 连接信息 spring.redis.host=<redis_host> spring.redis.port=<redis_port> spring.redis.password=<redis_password> ``` 4. 在应用中使用会话:在应用中使用 Spring Session 提供的 API 来管理会话。你可以使用 `@EnableRedisHttpSession` 注解启用 Spring Session,并使用 `@Autowired` 注入 `RedisOperationsSessionRepository` 或 `SessionRepositoryFilter`。 5. 确保会话数据正确存储和检索:通过 Spring Session + Redis会话数据将存储在 Redis 中。确保会话数据能够正确地存储和检索,以及与应用其他部分的交互正常。 6. 集群环境下的同步问题:如果你的应用在多个实例之间共享会话数据,并且使用 Redis 进行存储,需要注意在集群环境下的会话同步问题。你可以使用 Spring Session 提供的其他解决方案,如使用 Redis Pub/Sub 或 Redis Sentinel。 7. 监控和调优:在切换到 Spring Session + Redis 后,你可能需要重新评估和监控应用的性能和资源消耗情况,以确保它能够满足预期的性能需求。 以上是将会话管理从 Tomcat 切换到 Spring Session + Redis 时需要注意的一些事项。根据你的具体情况和需求,可能还需要调整其他相关配置和代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值