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

点击上方 "程序员小乐"关注, 星标或置顶一起成长

每天凌晨00点00分, 第一时间与你相约


每日英文

The sign of maturity is not when you start speaking big things,But, actually it is, When you start understanding Small things.

成熟的标志不是会说大道理,而是你开始去理解,身边的小事情。


每日掏心话

生活中,理解你的,许多时候,都能给你支持;误解你的,好多时候,还会对你质疑。


链接:jianshu.com/p/e4191997da56

在SpringBoot中使用Spring Session解决分布式会话共享问题
程序员小乐(ID:study_tech)第 814 次推文 图片来自百度

往日回顾:是时候扔掉Postman了,又一个被低估的IDEA插件出来了!


00 前言

如果你正在使用Java开发Web应用,想必你对HttpSession非常熟悉,但我们知道HpptSession默认使用内存来管理Session,如果将应用横向扩展将会出现Session共享问题。

Spring Session提供了一套创建和管理Servlet HttpSession的方案,以此来解决Session共享的问题,更为重要的是在Spring Boot中使用它极其简单。


01 正文


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。

  • 配置Nginx的负载均衡算法为ip_hash,这样每个请求按访问IP的hash结果分配,这样来自同一个IP的访客固定访问一个后端服务器,有效解决了动态网页存在的Session共享问题

  • 如果你使用Shiro管理Session,可以用Redis来实现Shiro 的SessionDao接口,这样Session便归Redis保管。

  • 设计一个Filter,利用HttpServletRequestWrapper,实现自己的 getSession()方法,接管创建和管理Session数据的工作。Spring-Session就是通过这样的思路实现的。


在Spring Boot中 集成 Spring Session

Spring Session 支持使用Redis、Mongo、JDBC、Hazelcast来存储Session,这里以Redis为例。

1、引入Maven依赖(本示例使用dependencyManagement,如果你没有使用它请添加<version>标签)/<version>

<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-data-redis/<artifactid>
/<dependency>
<dependency>
<groupid>org.springframework.session/<groupid>
<artifactid>spring-session/<artifactid>
/<dependency>

2、配置你的Spring Application,将你的application.properties加入以下配置。

spring.session.store-type=redis

仅此两步,便集成完毕,整个过程完全无痛、无感~

注意:如果你的Redis服务器不是使用本地默认配置(localhost:6379),需要配置你的Redis,如何配置?看这里。

我们来验证一下~

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

果然,Http Session已被Spring Session进行包装,我们可以依旧使用Http Session的API来进行编程。


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"
3) "spring:session:expirations:1490263320000"

使用redis-cli查看,发现Redis中也已保存相关数据。

参考

link.jianshu.com/?t=http://docs.spring.io/spring-session/docs/current/reference/html5/

欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,学习能力的提升上有新的认识,欢迎转发分享给更多人。


猜你还想看


阿里、腾讯、百度、华为、京东最新面试题汇集

Spring中如何使用责任链模式

Java对象不再使用时,为什么要赋值为 null ?

GitHub宣布收购npm,微软或成最大赢家!开源界野蛮竞争影响1200万开发者

关注订阅号「程序员小乐」,收看更多精彩内容
嘿,你在看吗?


分享到:


相關文章: