spring boot + redis 实现session共享分析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring boot + redis 实现session共享分析相关的知识,希望对你有一定的参考价值。

参考技术A

HttpSession是由servelet容器进行管理的。而我们常用的应用容器有 Tomcat/Jetty等, 这些容器的HttpSession都是存放在对应的应用容器的内存中,在分布式集群的环境下,通常我们使用Nginx或者LVS、Zuul等进行反向代理和负载均衡,因此用户请求是由一组提供相同服务的应用来进行处理,而用户最终请求到的服务由Nginx和LVS、Zuul进行确定。

那么问题就来了,我们怎样保证多个相同的应用共享同一份session数据?对于这种问题Spring为我们提供了Spring Session进行管理我们的HttpSession。项目地址: http://projects.spring.io/spring-session/

1.添加Spring session的包,而Spring session 是将HttpSession存放在Redis中,因此需要添加Redis的包。我们这里是用了Spring boot进行配置Rdies。

2.使用@EnableRedisHttpSession注解进行配置启用使用Spring session。

3.配置我们的Redis链接,我们这里使用的是Spring Boot作为基础进行配置,因此我们只需要在YML或者Properties配置文件添加Redis的配置即可。

4.创建请求的控制器来进行确定我们是否启用Session 共享。

5.将当前的工程拷贝一份.

通过上面请求显示的结果我们可以看出使用的是同一个Seesion,我们也可以查看下存在Redis中的Session。我这里使用RDM进行查看,我们还可以查看Session的属性。从图可以看出我们存进入的url属性。

我们从启动Spring Session的配置注解@EnableRedisHttpSession开始。
1.我们可以通过@EnableRedisHttpSession可以知道,Spring Session是通过RedisHttpSessionConfiguration类进行配置的。

2.我们在RedisHttpSessionConfiguration类种的注释可以知道,该类是用于创建一个过滤SessionRepositoryFilter。

3.探究下SessionRepositoryFilter类是在哪里创建\\创建过程\\作用。
(1)哪里创建:
通过搜索RedisHttpSessionConfiguration发现SessionRepositoryFilter的创建不是在RedisHttpSessionConfiguration,而是在父类SpringHttpSessionConfiguration中创建。

(2)SessionRepositoryFilter创建过程:

这里我们可以总结下:
Redis确保链接的情况下。
1.创建sessionRedisTemplate
2.创建RedisOperationsSessionRepository
3.创建SessionRepositoryFilter

(3)SessionRepositoryFilter的作用:
SessionRepositoryFilter的主要作用接管Seession的管理。我们可以从下面几个点知道为什么?

4.我们研究下SessionRepositoryRequestWrapper是怎样接管Session?

(1)存储Session的过程

当调用SessionRepositoryFilter.this.sessionRepository.save(session)完毕后,会判断当前的SessionId是否与请求的中的Cookie中SessionId一致,若不一致的情况下会调用onNewSession()方法,我们可以通过SpringHttpSessionConfiguration配置类的可以看到使用的是
CookieHttpSessionStrategy();
从CookieHttpSessionStrategy.onNewSession()方法可以看到是将SessionId写到Cookie中。

(2)获取Session的过程

我们根据源码的分析可以知道:
1.Spring Session 是通过SessionRepositoryFilter过滤器进行拦截,然后通过SessionRepositoryRequestWrapper继承HttpServletRequestWrapper进行管理Session。

2.Spring Session 为我们提供了3中存放的策略而每种策略提供对应的注解启动。分别为:
(1)NoSql形式的MongoDb:@EnableMongoHttpSession
(2)持久化形式的JDBC:@EnableJdbcHttpSession
(3)缓存形式的Redis:@EnableRedisHttpSession

3.Spring Session 共享Session过程:
(1)先过程过滤器存储将SessionID存放到本地的Cookie 和Redis中。
如果本地没有启用Cookie的情况下,Spring Session也就不能使用。
(2)获取Session的时候,先从请求中获取Session,Session不为空的情况下直接返回Session,若当前的Session为空的情况下,从Cookie中获取SessionId,判断SessionId不为空,再从Redis中获取Session,若从Redis中获取到的Session不为空将Session存放到请求中,再返回Session,如果从Redis中获取的Session为空,再创建新的Session并且添加到请求中,后返回Session。

以上是关于spring boot + redis 实现session共享分析的主要内容,如果未能解决你的问题,请参考以下文章

spring boot 结合Redis 实现工具类

Spring boot+redis实现消息发布与订阅

Spring boot+redis实现消息发布与订阅

spring boot + redis 实现session共享

spring boot + redis 实现session共享

Spring Boot实现Redis同数据源动态切换DB | Spring Cloud 31