当前位置: 首页 > 科技观察

在SpringBoot中使用Spring Session解决分布式会话共享问题

时间:2023-03-16 00:41:46 科技观察

使用SpringBoot中的SpringSession解决分布式session共享问题出现session共享问题。SpringSession提供了一套创建和管理ServletHttpSession的解决方案,解决了Session共享的问题,更重要的是在SpringBoot中使用极其简单。Session共享的问题HttpSession是由Servlet容器创建和管理的,像Tomcat/Jetty一样都是保存在内存中。如果我们将web应用横向扩展成一个分布式集群,然后使用LVS或者Nginx做负载均衡,那么同一个用户的Http请求可能会负载分布到两个不同的实例上。如何保证不同实例之间的负载Session分担成为了一个不得不解决的问题。最简单的方案是将Session数据保存在内存外统一的地方,比如Memcached/Redis。那么问题又来了,如何替换Servlet容器创建和管理HttpSession的实现呢?使用Servlet容器提供的插件功能自定义HttpSession的创建和管理策略,通过配置替换默认策略。但是这种方式有一个缺点,就是需要耦合Tomcat/Jetty等Servlet容器的代码。其实已经有这方面的开源项目,比如memcached-session-manager和tomcat-redis-session-manager。暂时只支持Tomcat6/Tomcat7。2.配置Nginx的负载均衡算法为ip_hash,让每个请求按照访问IP的hash结果进行分配,让同一个IP的访问者访问一个后端服务器,有效解决了存在的session共享问题动态网页。3、如果使用Shiro管理Session,可以使用Redis实现Shiro的SessionDao接口,这样Session就由Redis来保存。4、设计一个Filter,使用HttpServletRequestWrapper实现自己的getSession()方法,接手创建和管理Session数据的工作。Spring-Session就是通过这个思路实现的。在SpringBoot中集成SpringSessionSpringSession支持使用Redis、Mongo、JDBC、Hazelcast来存储Session。这里以Redis为例。1.引入Maven依赖(本例使用dependencyManagement,如果不使用,请添加标签)org.springframework.bootspring-boot-starter-data-redisorg.springframework.sessionspring-session2.配置你的Spring应用,添加你的应用.属性添加如下配置。spring.session.store-type=redis只有这两步,集成完成,整个过程完全无痛无感~注意:如果你的Redis服务器没有使用本地默认配置(localhost:6379),你需要配置你的Redis,如何配置?看这里。我们来验证一下~果然HttpSession已经被SpringSession封装了,我们仍然可以使用HttpSessionAPI进行编程。Cookies也正常创建,Key为SESSION。127.0.0.1:6379>keys*1)"spring:session:sessions:083706a8-b2d8-480c-8b88-eafc798e7269"2)"spring:session:sessions:expires:083706a8-b2d8-480c-8b88-eafc798e7269""spring:session:expirations:1490263320000"使用redis-cli查看,发现相关数据也已经保存在Redis中了。