嘿,大家好,今天我要更新的内容是session共享。。。
开发背景
由于是比较老的项目(struts2+spring2.5+ibatis),且没有使用redis进行缓存,项目中需要缓存的东西通通都放到了session中,我们想要达到这样一个目的,使用Nginx来负载两个tomcat,这样我们在更新或者升级代码的时候,可以保证另外一个项目还可以继续运行,用户还可以继续访问。那么问题来了,当tomcat-A停止运行的时候,另一个tomcat-B中的session中并没有tomcat-A中的我们缓存的数据,则不能保证服务正常运行。
所以呢,这里有两个解决方案,方案A:将所有存取session的操作改到存取redis中,但是由于存取session的地方太多了,工作量过大,而且麻烦,所以这种方案就被pass了,然后我们采取方案B:实现session的共享的方式,使用这种方式的好处就是,不改变原来的代码逻辑,而且简单。
顺着这条路我开始研究session共享,最终找到两种可行的方法:
一:tomcat-session-redis
使用tomcat+redis实现session共享,下面是操作步骤以及在配置tomcat-session-redis的时候遇到的一些坑
1.引入三个jar包:commons-pool2-2.2.jar、jedis-2.6.0.jar和tomcat-redis-session-manager-1.2-tomcat-7.jar放在tomcat的 lib下面。(这里博主的jdk和tomcat的版本都是7,大家有兴趣可以尝试下别的版本,点击链接可以下载不同版本的tomcat-redis-session的jar包)
2.然后tomcat的context.xml配置里增加如下配置,不要加错了哦,博主蠢蠢的把这面这段配置加到了server.xml中导致报错,好久才发现。。。
其中sessionPersistPolicies有三种策略,上文中的是默认策略,还有另外两种保存策略,大家可以根据需要选择配置即可
- SAVE_ON_CHANGE:每次session.setAttribute()或被session.removeAttribute()称为会话都将被保存。注意:此功能无法检测对已存储在特定会话属性中的对象所做的更改。权衡:此选项会稍微降低性能,因为会话的任何更改都会将会话同步保存到Redis。
- ALWAYS_SAVE_AFTER_REQUEST:每次请求后强制保存,无论管理器是否检测到会话更改。如果对已存储在特定会话属性中的对象进行更改,则此选项特别有用。权衡:如果并非所有请求都改变了会话,则此选项实际上会增加竞争条件的可能性。
配置完成后我们分别启动Nginx(Nginx.conf配置在文章底部),redis,tomcat-A,tomcat-B,此时查看两个tomcat服务的sessionId是否一致,如果一致,则说明我们配置成功了。。。
遇到的问题
下面是我在配置时遇到的几个问题,大家如果在配置的时候,有遇到和我相同问题的可以参考一下:
1.配置要放在context.xml中,而不是server.xml。估计只有我会犯这种错误吧,哈哈哈哈~~~
2.保证tomcat配置session交由redis。
2.应用的session管理交由tomcat管理,如果应用针对session做了个性化管理,session 共享会失效,博主就是没有发现项目中的web.xml对session做了过期时间的设置,导致session 共享会失效。
3.session里不能存入null,因为不能getByte(null),这也是我遇到的一个坑,明明都是配置好了,sessionId也已经相同了,后来查看tomcat-redis-session.jar的源码发现,将数据通过getByte()的方式序列化到了redis中,但是项目中存在set一个null到session中,导致一直报错,在相应位置位置做了非空判断之后,session共享正常。。。
至此Nginx+tomcat+redis配置session共享测试成功!
二:spring-session
注意,spring-session这种方式对spring的版本有一定的要求,由于公司项目使用的spring版本较老,不支持spring-session,所以将spring版本升级到4.3。ps:spring session支持的spring版本最低为spring 4.2以上
具体操作步骤如下:
1.确保spring的版本在4.2之上,如为满足条件需先升级spring的版本
2.引入spring session与redis相关的jar包,分别为:commons-pool2-2.4.2.jar,jedis-2.9.0.jar,spring-data-redis-1.7.3.RELEASE.jar,spring-session-1.2.2.RELEASE.jar,由于博主项目较老,而且还不是maven管理的,所以这里直接引入相关jar包,如果是maven项目的小伙伴在pom中直接引入相关jar包即可
3. 在web.xml添加过滤器:(放在所有过滤器配置之前)
4.applicationContext.xml文件配置相关redis会话连接管理
遇到的问题
5.至此其实配置已经结束了,但是其实还没完,这样配置完成之后会存在List、Map、TreeMap等集合不能序列化,不能存入redis的问题,spring-session默认使用的序列化方式是JdkSerializationRedisSerializer,所以我们要修改spring-session默认的序列化方式,使用我们自定义的序列化方式SessionSerializer,另外我们要把需要存取redis的实体类实现序列化接口~~~
RedisHttpSessionConfig :
SessionSerializer :
配置完成后我们分别启动Nginx(Nginx.conf配置在文章底部),redis,tomcat-A,tomcat-B,此时查看两个tomcat服务的sessionId是否一致,如果一致,则说明我们配置成功了。。。
以上就是实现session共享的的两种方式。。。
Nginx.conf配置文件
使用Nginx负载均配两个tomcat配置如下:
今天的更新到这里就结束了,拜拜!!!
感谢一路支持我的人,您的关注是我坚持更新的动力,有问题可以在下面评论留言或随时与我联系。。。。。。
QQ:850434439
微信:w850434439
EMAIL:gathub@qq.com
如果有兴趣和本博客交换友链的话,请按照下面的格式在评论区进行评论,我会尽快添加上你的链接。
网站名称:GatHub-HongHui'S Blog
网站地址:https://www.gathub.cn/
网站描述:不习惯的事越来越多,但我仍在前进…就算步伐很小,我也在一步一步的前进。
网站Logo/头像:[头像地址]