在我方供应链项目分布式部署的环境下,需要在统一网关服务中管理访问的Session,即无论访问请求路由到哪一个网关服务环境,使用的都是相同的HttpSession,这样就保证了在用户登录之后,能够使用统一的Session来处理鉴权和其他逻辑,这对于分布式系统的用户会话管理是必要的。为了能够达到这个目的,我们引入了SpringSession。

SpringSession是什么

SpringSession是Spring框架大集合下的一个子组件,使用Redis来备份Web服务访问生成的(被加工过的)HttpSession,当你在使用SpringBoot框架的时候,你能够很方便的集成和使用它。

SpringSession如何使用

1、增加依赖

当你在使用SpringBoot框架并采用maven来管理依赖库时,你只需增加下面的依赖:

 <dependencies>
<!-- ... --> <dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
</dependencies>

幸运的是,当你在使用SpringBoot框架时,你不需要手动指定依赖的具体版本,它会帮你自动管理。

2、SpringBoot配置项

得益于SpringBoot的自动配置管理支持,在设置使用Redis备份SpringSession时,我们只需要在application.properties增加如下内容:

# Session store type.
spring.session.store-type=redis

在如上的配置驱动下,我们再在SpringBoot的配置管理下增加@EnableRedisHttpSession注解,它会自动创建一个名称为SpringSessionReposityFilter且实现了Filter接口的(过滤器)类,这个过滤器将负责替换HttpSession的实现为SpringSession。

更多关于SpringSession的配置如下:

# Session timeout. If a duration suffix is not specified, seconds is used.
server.servlet.session.timeout= # Sessions flush mode.
spring.session.redis.flush-mode=on-save # Namespace for keys used to store sessions.
spring.session.redis.namespace=spring:session

3、配置Redis连接

其实SpringBoot会自动创建一个叫做RedisConnectionFactory的类来管理SpringSession与Redis服务的连接,默认是连接到localhost端口为6379的Redis服务,但是在生产环境中,那就必须将这种与Redis服务器连接的配置进行自定义更改,你可以按照如下代码清单所例举的方式将配置追加到application.properties文件中:

# Redis server host.
spring.redis.host=localhost # Login password of the redis server.
spring.redis.password= # Redis server port.
spring.redis.port=

当然,如果你的SpringBoot中自有管理与Redis服务器的连接,你同样可以在你的Configuration将这个连接复用给这里的配置,比如你使用JedisShardInfo。

以下是使用JedisShardInfo的代码参考:

 @Bean("jedisShardInfo")
public JedisShardInfo jedisShardInfo(@Value("${jedis.redis.uri}") String uri,
@Value("${catalog.redis.tesla}") String redisCatalog) {
String redisUri = uri;
redisUri = getRedisUri(redisCatalog, redisUri);
return new JedisShardInfo(redisUri);
} private String getRedisUri(String redisCatalog, String redisUri) {
if(!StringUtils.isEmpty(redisCatalog)) {
log.info("===> Redis use unified configuration.");
DataSourceInstanceConfig dbInstanceConfig = DBLoader.getDataSourceInstanceConfig(redisCatalog);
RedisServerInfo serverInfo = dbInstanceConfig.getServer(RedisServerInfo.class).get(0);
redisUri = REDIS_URI_PREFIX.concat(serverInfo.getPassword()).concat("@")
.concat(serverInfo.getHost()).concat(":")
.concat(serverInfo.getPort()).concat("/")
.concat(serverInfo.getDb());
log.info("===> redis_uri: {}", redisUri);
}
return redisUri;
} @Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 172800)
public class HttpSessionConfig {
@Bean
public static ConfigureRedisAction configureRedisAction() {
return ConfigureRedisAction.NO_OP;
} @Bean
public JedisConnectionFactory connectionFactory(@Autowired @Qualifier("jedisShardInfo") JedisShardInfo jedisShardInfo){
return new JedisConnectionFactory(jedisShardInfo);
}
}

4、Servlet容器初始化

在SpringBootConfiguration的配置驱动下,自动创建的SpringSessionRepositoryFilter将负责替换系统的HttpSession为SpringSession并保存于redis中,为了这个拦截器能够发挥作用,Spring需要将这个过滤器纳入配置管理,最后我们还需要确保Servlet容器能够正确的使用这个拦截器拦截到所有请求,幸运的是,SpringBoot为我们顾及到了所有的这些步骤。

SpringSession的实现原理是什么

和我们使用Tomcat的HttpSession不同的是,我们将这个会话内容持久化到了Redis中。SpringSession将HttpSession替换为一种新的实现,并将它保存到了Redis中,也就是当我们的SpringSecurity的SecurityContextPersistenceFilter在保存了SecurityContext到HttpSession之后,就会触发这个替换机制保存到Redis中。

当我们发起访问请求的时候,系统会创建一个HttpSession,而SpringSesion会创建一个名称为SESSION的cookie放到你浏览器的中,这个cookie的内容包含了你session的ID,你可以在你的Chrome浏览器控制台中查看到。

于此同时,你也可以在你的redis服务器中看到,找到以application.properties中配置的命名空间开头的key值,然后你会看到包含和浏览器上看到的SESSION相同内容的key,当然你可以在redis服务器中使用redis-cli命令去查看或者删除它。

当你浏览器每次发起Http请求到服务端时,都会携带这个cookie内容,服务端SpringSession接受到这个cookie值之后就自动去redis中找到相同的会话Session,由此来识别出是同一个用户进行的访问。

参考资料

1、https://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot-redis.html

2、http://blog.didispace.com/spring-session-xjf-2/

使用SpringSession管理分布式系统的会话Session的更多相关文章

  1. 使用SpringSession管理分布式会话时遇到的反序列化问题

    关于SpringSession相关的介绍和使用指南,可移步如下网址: [SpringSession管理分布式系统的会话Session] https://www.cnblogs.com/captaina ...

  2. java的会话管理:Cookie和Session

    java的会话管理:Cookie和Session 1.什么是会话 此处的是指客户端(浏览器)和服务端之间的数据传输.例如用户登录,购物车等 会话管理就是管理浏览器客户端和服务端之间会话过程产生的会话数 ...

  3. 简单PHP会话(session)说明

    现在程序员愈发的不容易了,想要精通,必然要寻本溯源,这其实与目前泛滥的愈发高级的语言以及众多的框架刚好相反,因为它们在尽可能的掩盖本源使其简单,个人称之为程序员学习悖论. 注:作者接触web开发和ph ...

  4. spring-session实现分布式集群session的共享

    前言 HttpSession是通过Servlet容器创建和管理的,像Tomcat/Jetty都是保存在内存中的.但是我们把应用搭建成分布式的集群,然后利用LVS或Nginx做负载均衡,那么来自同一用户 ...

  5. Tensorflow会话Session

    转载自: http://blog.csdn.net/Hanging_Gardens/article/details/72784392 https://www.cnblogs.com/hypnus-ly ...

  6. Java通过遍历sessionId获取服务器所有会话session

    Servlet2.1之后不支持SessionContext里面getSession(String id)方法,也不存在遍历所有会话Session的方法.但是,我们可以通过HttpSessionList ...

  7. spring-session实现分布式集群session的共享(转)

    原文: https://www.cnblogs.com/youzhibing/p/7348337.html HttpSession是通过Servlet容器创建和管理的,像Tomcat/Jetty都是保 ...

  8. MyBatis之会话Session原理

    MyBatis 之会话 Session 执行逻辑 1.SQL 会话工厂构建器类 SqlSessionFactoryBuilder 的 build 方法用于构建 SqlSessionFactory 类的 ...

  9. 第二十三章 多项目集中权限管理及分布式会话——《跟我学Shiro》

    二十三章 多项目集中权限管理及分布式会话——<跟我学Shiro> 博客分类: 跟我学Shiro 跟我学Shiro  目录贴:跟我学Shiro目录贴 在做一些企业内部项目时或一些互联网后台时 ...

随机推荐

  1. new LayoutParams 使用

    ImageView imageView = new ImageView(mcontext); LayoutParams layoutParams = new LayoutParams(150,130) ...

  2. Flask09 原始输出、转义、XSS攻击、过滤器???

    1 怎么在jinja模板中原始输出模板语法 1.1 用双引号引起来后放到 {{ }} 中 例如 {{ "{{}}" }} 输出 1.2 利用raw 例如 {% raw %} {% ...

  3. 报错:defined for 'courierAction_pageQuery' in namespace '/'Error creating bean with name 'cn.itcast.bos.web.action.base.CourierAction': Injection of autowired dependencies failed; nested exception is or

    No qualifying bean of type [cn.itcast.bos.web.service.base.CourierService] found for dependency: exp ...

  4. OpenCV 鼠标手动绘制掩码图像

    OpenCV 鼠标手动绘制掩码图像 完整的代码: #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui ...

  5. 通过HBase Shell与HBase交互

    出处:http://www.taobaotest.com/blogs/1604 业务开发测试HBase之旅二:通过HBase Shell与HBase交互 yedu 发表于:2011-10-11 浏览: ...

  6. 33、VCF格式

    转载:http://blog.sina.com.cn/s/blog_7110867f0101njf5.html http://www.cnblogs.com/liuhui0622/p/6246111. ...

  7. 30、 bowtie和bowtie2使用条件区别及用法

    转载:http://blog.csdn.net/soyabean555999/article/details/62235577 一.转录组还是基因组? map常用的工具有bowtie/bowtie2, ...

  8. 第 2 章 Python 语言入⻔

    目录 2.1低而长的学习曲线 2.2Python的优势 2.3在你的计算机中安装Python 2.4如何运行Python程序 2.5文本编辑器 2.6寻求帮助 Python语言是一种流行的编程语言,在 ...

  9. Getting the System Version

    #include <windows.h>#include <tchar.h>#include <stdio.h>#include <strsafe.h> ...

  10. Entity Framework Code-First(4):Simple Code First Example

    Simple Code First Example: Let's assume that we want to create a simple application for XYZ School. ...