nginx+spring-session+redis 实现session共享
session共享、除开ip_hash、url_hash之外的记录,过程不表、共同学习
代码实现:
全程加配置即可,无需改变原始业务逻辑代码
1、Pom依赖
org.springframework.session spring-session-data-redis 1.2.1.RELEASE redis.clients jedis 2.8.1
2、Web.xml配置
注:最好放在所有filter的前面,防止被其他filter先拦截springSessionRepositoryFilter org.springframework.web.filter.DelegatingFilterProxy springSessionRepositoryFilter /*
3、Redis连接配置(只需基本连接即可、无需暴露客户端使用属性)
OK 代码End!!
测试如下:
1.准备一个nginx 起两台tomcat ,并搭建一个负载(轮询方式即可、无需设置备机,不要设置ip_hash\url_hash 否则失去了这一套共享的意义) 具体实现不再啰嗦、之前的文章有提到
2.打印sessionId、看nginx转发到不同的tomcat上sessionId是否相同(没日志、直接先起一台tomcat、请求得到sessionID之后、记录该id,down掉tomcat,再启另一台,再访问,看得到的sessionID与之前的id是否一致)
测试结果:
1.未加session共享之前的结果:sessionID 不同的tomcat 得到的不同
2.加了之后,相同。
原理流转:
原理分析如下:
Req----nginx----tomcat---filter
之前的session由tomcat创建,现在交由Spring-session中的SessionRepository并保存到redis里。
Req流转:
1. Web.xml加载
content-param --> listener --> filter
2.加载spring监听之后 contextInitialized 方法执行 初始化根web应用程序上下文。
3.初始化我们配置的各种bean,加载JedisConnectionFactory初始化
4. 初始化我们配置的各种bean,进入到我们配置的RedisHttpSessionConfiguration
5.点开RedisHttpSessionConfiguration 可以看到它里面创建了N个bean,主要的几个有springSessionRepositoryFilter(这是他父类里的)、sessionRedisTemplate、sessionRepository ,由这3个bean 实例化redistemple,设置保存的存储类型为Hash,而它的参数RedisConnectionFactory由3(JedisConnectionFactory)提供
6.到filter拦截DelegatingFilterProxy 一看卧槽这是个代理,如果不指定init-param参数的话,DelegatingFilterProxy就会把filter-name作为要查找的Bean对象,这也是DelegatingFilterProxy类的作用。我们配置的是springSessionRepositoryFilter 这个东西再哪里呢?
7.第5步里面RedisHttpSessionConfiguration 初始化时会加载,它继承了OncePerRequestFilter、OncePerRequestFilter又继承了filter,就是这个玩意替换了javax.servlet.http.HttpSession支持org.springframework.session.Session
8.点进去可以看到在OncePerRequestFilter中dofilter里面加载了doFilterInternal方法,该方法被springSessionRepositoryFilter 自定义实现,除了包装了一套HttpServletRequest、HttpServletRespouse ,在finally里执行了commitSession方法,这个方法里执行了save()方法,该方法保存session用,底层执行的是RedisOperationsSessionRepository ,到这里终于和redis扯上关系了,底层通过RedisTemplate 进行存储操作key为sessionId value 为session对象放的是map
9.session过期策略,定期job 每分钟一次执行上一分钟过期的key即sessionid 方法cleanExpiredSessions,默认失效时间 1800s,自定义再maxInactiveIntervalInSeconds设置
参考:
https://blog.csdn.net/weixin_41070431/article/details/80421627
https://blog.csdn.net/u010648555/article/details/79491988
https://blog.csdn.net/xlgen157387/article/details/60321984