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

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

前言

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

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

Session共享的问题

HttpSession是通过Servlet容器创建和管理的,像Tomcat/Jetty都是保存在内存中的。如果我们将Web应用横向扩展搭建成分布式的集群,然后利用LVS或Nginx做负载均衡,那么来自同一用户的Http请求将有可能被负载分发到两个不同的实例中去,如何保证不同实例间Session共享成为一个不得不解决的问题。

最简单的解决方法就是把Session数据保存到内存以外的一个统一的地方,例如Memcached/Redis中。那么问题又来了,如何替换掉Servlet容器创建和管理HttpSession的实现呢?

  1.  利用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就是通过这样的思路实现的。

在Spring Boot中 集成 Spring Session

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

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

  1. <dependency>  
  2.            <groupId>org.springframework.boot</groupId>  
  3.            <artifactId>spring-boot-starter-data-redis</artifactId>  
  4.        </dependency>  
  5.        <dependency>  
  6.            <groupId>org.springframework.session</groupId>  
  7.            <artifactId>spring-session</artifactId>  
  8.        </dependency> 

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

  1. spring.session.store-type=redis 

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

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

我们来验证一下~

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

Cookies 也正常创建,Key为SESSION。 

  1. 127.0.0.1:6379> keys *  
  2. 1) "spring:session:sessions:083706a8-b2d8-480c-8b88-eafc798e7269"  
  3. 2) "spring:session:sessions:expires:083706a8-b2d8-480c-8b88-eafc798e7269"  
  4. 3) "spring:session:expirations:1490263320000" 

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

 

责任编辑:庞桂玉 来源: Java知音
相关推荐

2015-08-19 15:45:33

2023-11-20 15:32:29

2020-08-25 07:35:07

session分布式抽象

2023-12-29 08:18:31

Session分布式系统微服务

2019-07-31 08:44:27

Session共享Memcache

2014-05-08 14:38:26

tornadoredissession

2021-03-08 09:56:24

存储分布式Session

2021-05-08 08:01:05

Session登录浏览器

2009-07-30 12:30:27

ASP.NET中使用S

2021-12-14 08:19:59

系统分布式网络

2021-12-15 07:24:56

分布式系统时钟

2023-01-13 07:39:07

2023-03-30 07:48:46

接口鉴权SpringBoot

2023-03-07 08:19:16

接口幂等性SpringBoot

2010-04-21 17:50:59

共享库bada

2022-10-26 17:28:41

分布式事务seata

2022-03-24 07:51:27

seata分布式事务Java

2022-01-10 11:58:51

SpringBootPulsar分布式

2017-06-05 15:51:54

分布式Logical Tim算法

2023-09-04 08:12:16

分布式锁Springboot
点赞
收藏

51CTO技术栈公众号