Web项目Session管理是一个很重要的话题, 涉及到系统横向扩展, SpringBoot已经为共享Session很好的解决方案, 这篇文章关注使用Redis共享会话, 同时这也是最常用的方法.

============================
pom.xml 增加依赖
============================
SpringBoot2 已经将Redis底层客户端从Jedis切换为Lettuce库, Lettuce 是基于Netty的实现, 比 Jedis 更加高效, 并且是线程安全的, 能满足多线程环境下并发需求, 同时支持线程池.

使用 Lettuce 客户端(推荐), pom.xml的依赖有:

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-redis</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.apache.commons</groupId>
  7. <artifactId>commons-pool2</artifactId>
  8. </dependency>
  9.  
  10. <!-- Session 依赖 -->
  11. <dependency>
  12. <groupId>org.springframework.session</groupId>
  13. <artifactId>spring-session-data-redis</artifactId>
  14. </dependency>
  15.  
  16. <!-- 添加缓存支持, 暂时没用上 -->
  17. <dependency>
  18. <groupId>org.springframework.boot</groupId>
  19. <artifactId>spring-boot-starter-cache</artifactId>
  20. </dependency>
  21. <dependency>
  22. <groupId>org.springframework.boot</groupId>
  23. <artifactId>spring-boot-starter-test</artifactId>
  24. <scope>test</scope>
  25. </dependency>

如果要使用 Jedis 客户端, pom.xml还需要加上 jedis 依赖包.

  1. <dependency>
  2. <groupId>redis.clients</groupId>
  3. <artifactId>jedis</artifactId>
  4. </dependency>

============================
application.properties 配置
============================

  1. ## Spring cache 设置
  2. # 使用redis作为cache(暂时没用上)
  3. spring.cache.type=redis
  4.  
  5. ## Spring Session 设置
  6. # 确保 application.properties 文件设定session存储为redis , SpringBoot2支持多种形式的存储, 包括 redis,mongo,jdbc,hazelcase,none等.
  7. spring.session.store-type=redis
  8. # 指定 session的过期时间,也可在@EnableRedisHttpSession注释参数中指定
  9. server.servlet.session.timeout=
  10. # Sessions flush mode, 默认是on-save,还可以是 immediate 模式,
  11. spring.session.redis.flush-mode=on-save
  12. # 指定 redis中 session 对应的命名空间
  13. spring.session.redis.namespace=spring:session
  14.  
  15. ## redis 公共设置
  16. spring.redis.host=localhost
  17. # Redis服务器连接端口
  18. spring.redis.port=
  19. # Redis服务器连接密码(默认为空)
  20. spring.redis.password=
  21. # 连接超时时间(毫秒)
  22. spring.redis.timeout=
  23. # Redis默认情况下有16个分片,这里配置具体使用的分片
  24. spring.redis.database=
  25.  
  26. ## lettuce 特有的配置:
  27. # 连接池最大连接数(使用负值表示没有限制) 默认
  28. spring.redis.lettuce.pool.max-active=
  29. # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -
  30. spring.redis.lettuce.pool.max-wait=-
  31. # 连接池中的最大空闲连接 默认
  32. spring.redis.lettuce.pool.max-idle=
  33. # 连接池中的最小空闲连接 默认
  34. spring.redis.lettuce.pool.min-idle=
  35.  
  36. ## jedis 特有的配置, 只需要将上面配置文件的 lettuce 文字替换为 jedis 即可.
  37. # 连接池最大连接数(使用负值表示没有限制) 默认
  38. spring.redis.jedis.pool.max-active=
  39. # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -
  40. spring.redis.jedis.pool.max-wait=-
  41. # 连接池中的最大空闲连接 默认
  42. spring.redis.jedis.pool.max-idle=
  43. # 连接池中的最小空闲连接 默认
  44. spring.redis.jedis.pool.min-idle=

spring.session.redis.flush-mode=on-save 或 immediate
on-save模式不是在每次通过Session类获取或保存会话信息就调用Redis操作. 对于获取会话信息, 它先尝试从内存HashMap中读取值, 如果没有, 才调用Redis的HMGET操作; 对于保存会话信息, 先保存到内存中, 然后执行web请求的其他工作, 最后才调用Redis的HMSET操作.

============================
增加一个 SessionConfig.java
============================

  1. SessionConfig.java 文件
  2. @Configuration
  3. @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600)
  4. public class SessionConfig {
  5. }
  6.  
  7. //@Configuration
  8. //@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600)
  9. //public class SessionConfig {
  10. // @Bean
  11. // public RedisTemplate<Object, Object> sessionRedisTemplate(RedisConnectionFactory connectionFactory) {
  12. // RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
  13. // template.setKeySerializer(new StringRedisSerializer());
  14. // template.setHashKeySerializer(new GenericJackson2JsonRedisSerializer());
  15. // template.setConnectionFactory(connectionFactory);
  16. // return template;
  17. // }
  18. //}

SesionConfig.java 是一个空的类, 该类其实并不是必需的, 必需的其实是@EnableRedisHttpSession注解, 我们可以将 @EnableRedisHttpSession 注解直接加到主程序类, 这样就可以省掉SesionConfig.java .
加上@EnableRedisHttpSession 注解后, SpringBoot程序在Servlet container 初始化时, 会创建一个 springSessionRepositoryFilter bean, 其实就是一个Filter, 该Fiber负责用 Spring Session替换默认的HttpSession实现.

============================
增加一个 HelloworldController.java文件
============================

  1. @Controller
  2. @RequestMapping("/test")
  3. public class HelloworldController {
  4. @RequestMapping("/set")
  5. @ResponseBody
  6. public String set(HttpServletRequest req) {
  7. HttpSession session=req.getSession();
  8. session.setAttribute("testKey", "testValue");
  9. return "已经设置session:testKey=testValue, SessionId:"+session.getId();
  10. }
  11.  
  12. @RequestMapping("/query")
  13. @ResponseBody
  14. public Object query(HttpServletRequest req) {
  15. HttpSession session=req.getSession();
  16. Map<String, Object> map = new HashMap<String, Object>();
  17. map.put("SessionId", session.getId());
  18. map.put("testKey", session.getAttribute("testKey"));
  19. return map;
  20. }
  21. }

============================
测试
============================
测试方法很简单, 使用同一个浏览器先后访问两个应用服务器, 如果能获得同一个session id, 就说明能共享 session 了.

首先登陆Redis中, 清空所有的key.

maven 打包一下这个项目, 执行下面的命令启动两个服务程序.

C:\Windows\system32>java -Dserver.port=8080 -jar D:\eclipse_workspace\redis\target\redisSessionDemo.jar
C:\Windows\system32>java -Dserver.port=9000 -jar D:\eclipse_workspace\redis\target\redisSessionDemo.jar

在同一个浏览器两个tab页中, 依次访问上面两个服务器:
http://localhost:8080/test/set
http://localhost:9000/test/query
第一个访问8080服务器, 设置session的属性testKey, 第2个访问9000端口, 可以看到页面上输出的session id 是一致的,并能获取到该session的testKey属性.

登录 redis, 输入 keys *session* 命令, 可以查看到这个session id 已经缓存在redis中了.

使用 redis type命令得知该session key是 hash table类型,

使用 redis hgetall 命令可以查看该hash table的所有字段和取值.

============================
参考
============================
http://www.cnblogs.com/chenpi/p/6347299.html
https://www.jianshu.com/p/ece9ac8e2f81
https://segmentfault.com/a/1190000012490895#idea-redis-
http://www.cnblogs.com/csonezp/p/6102924.html
https://blog.csdn.net/dream_broken/article/details/72676679
https://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot-redis.html

SpringBoot系列: Redis 共享Session的更多相关文章

  1. SpringBoot,Security4, redis共享session,分布式SESSION并发控制,同账号只能登录一次

    由于集成了spring session ,redis 共享session,导致SpringSecurity单节点的session并发控制失效, springSession 号称 无缝整合httpses ...

  2. SpringBoot+Shiro+Redis共享Session入门小栗子

    在单机版的Springboot+Shiro的基础上,这次实现共享Session. 这里没有自己写RedisManager.SessionDAO.用的 crazycake 写的开源插件 pom.xml ...

  3. SpringBoot SpringSession redis 共享 SESSION

    号称无缝整合httpsession 共享, 但注意如果存在第三方框架,例如SESSION并发控制,这个是需要自己重写session名单的. 关于redis session 共享 的session并发控 ...

  4. linux下实现redis共享session的tomcat集群

    为了实现主域名与子域名的下不同的产品间一次登录,到处访问的效果,因此采用rediss实现tomcat的集群效果.基于redis能够异步讲缓存内容固化到磁盘上,从而当服务器意外重启后,仍然能够让sess ...

  5. Nginx+tomcat集群使用redis共享session

    一 :nginx负载均衡 当Tomcat当做独立的Servlet容器来运行时,可看做是能运行Java Servlet的独立Web服务器. 此外 Tomcat还可以作为其他Web服务器进程内或者进程外的 ...

  6. Tomcat7.0.99集群使用Redis共享session方案

    以前配置过给予多播的session共享方案,这回再配置一个redis共享session的. 先小小的炫耀一下: 相信大家要做Tomcat+Redis+session配置,遇到的头号麻烦就是编译的tom ...

  7. Spring Boot 使用 Redis 共享 Session 代码示例

    参考资料 博客:spring boot + redis 实现session共享 1. 新建 Maven 工程 我新建 spring-boot-session-redis maven 工程 2. 引入 ...

  8. SpringBoot使用Redis共享用户session信息

    SpringBoot引入Redis依赖: <dependency> <groupId>org.springframework.boot</groupId> < ...

  9. springboot整合redis存放session

    y进入maven依赖: <!--spring boot 与redis应用基本环境配置 --> <dependency> <groupId>org.springfra ...

随机推荐

  1. zabbix监控概念

    监控:数据采集 --> 数据存储 -->  数据展示 报警:采集到的数据超出阈值 SNMP:Simple Network Management Protocol(只能实现数据采集) NMS ...

  2. [luogu1486][bzoj1503][NOI2004]郁闷的出纳员【平衡树treap】

    题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...

  3. [2017-7-27]Android Learning Day5

    总结篇! 吭哧吭哧了三天,最近不断研究<第一行代码:第二版>170多页的那个新闻实践项目,虽然也没有用到数据库和一些Web爬虫的知识,新闻数据都是随机生成的字符串...... 但还是很开心 ...

  4. 使用zabbix监控mariadb性能状态

    0x01 前言 zabbix内置Mysql的监控模版,因为mariadb和Mysql两者的相关性,所以这个模版也能用在mariadb services上. 0x02 Mysql 首先要在mariadb ...

  5. C语言学习记录之一

    1. while语句 2. 循环嵌套 3. 数组 4. 排序 1. while 由于上节课时间有限,介绍完for循环后没有来得及讲while语句.简单来讲,while也是一种循环结构,先看一个例子: ...

  6. OpenLayers学习笔记(三)— QML与HTML通信之 地图上点击添加自由文本

    实现在地图随意点击,弹出文本输入框,输入任意文字,完成自由文本添加的功能 作者: 狐狸家的鱼 GitHub:八至 本文链接:地图上点击添加自由文本 关于如何QML与HTML通信已经在上一篇文章 QML ...

  7. Vue+koa2开发一款全栈小程序(1.课程介绍+2.ES6入门)

    1.课程介绍 1.课程概述 1.做什么? Vue+koa2开发一款全栈小程序 2.哪些功能? 个人中心.图书列表.图书详情.图书评论.个人评论列表 3.技术栈 小程序.Vue.js.koa2.koa- ...

  8. 详解python的垃圾回收机制

    python的垃圾回收机制 一.引子 我们定义变量会申请内存空间来存放变量的值,而内存的容量是有限的,当一个变量值没有用了(简称垃圾)就应该将其占用的内存空间给回收掉,而变量名是访问到变量值的唯一方式 ...

  9. 使用webdriver+urllib爬取网页数据(模拟登陆,过验证码)

    urilib是python的标准库,当我们使用Python爬取网页数据时,往往用的是urllib模块,通过调用urllib模块的urlopen(url)方法返回网页对象,并使用read()方法获得ur ...

  10. Codeforces Round #523 (Div. 2) B Views Matter

    传送门 https://www.cnblogs.com/violet-acmer/p/10005351.html 这是一道贪心题么???? 题意: 某展览馆展览一个物品,此物品有n堆,第 i 堆有a[ ...