SpringBoot系列: Redis 共享Session
Web项目Session管理是一个很重要的话题, 涉及到系统横向扩展, SpringBoot已经为共享Session很好的解决方案, 这篇文章关注使用Redis共享会话, 同时这也是最常用的方法.
============================
pom.xml 增加依赖
============================
SpringBoot2 已经将Redis底层客户端从Jedis切换为Lettuce库, Lettuce 是基于Netty的实现, 比 Jedis 更加高效, 并且是线程安全的, 能满足多线程环境下并发需求, 同时支持线程池.
使用 Lettuce 客户端(推荐), pom.xml的依赖有:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency> <!-- Session 依赖 -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency> <!-- 添加缓存支持, 暂时没用上 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
如果要使用 Jedis 客户端, pom.xml还需要加上 jedis 依赖包.
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
============================
application.properties 配置
============================
## Spring cache 设置
# 使用redis作为cache(暂时没用上)
spring.cache.type=redis ## Spring Session 设置
# 确保 application.properties 文件设定session存储为redis , SpringBoot2支持多种形式的存储, 包括 redis,mongo,jdbc,hazelcase,none等.
spring.session.store-type=redis
# 指定 session的过期时间,也可在@EnableRedisHttpSession注释参数中指定
server.servlet.session.timeout=
# Sessions flush mode, 默认是on-save,还可以是 immediate 模式,
spring.session.redis.flush-mode=on-save
# 指定 redis中 session 对应的命名空间
spring.session.redis.namespace=spring:session ## redis 公共设置
spring.redis.host=localhost
# Redis服务器连接端口
spring.redis.port=
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接超时时间(毫秒)
spring.redis.timeout=
# Redis默认情况下有16个分片,这里配置具体使用的分片
spring.redis.database= ## lettuce 特有的配置:
# 连接池最大连接数(使用负值表示没有限制) 默认
spring.redis.lettuce.pool.max-active=
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -
spring.redis.lettuce.pool.max-wait=-
# 连接池中的最大空闲连接 默认
spring.redis.lettuce.pool.max-idle=
# 连接池中的最小空闲连接 默认
spring.redis.lettuce.pool.min-idle= ## jedis 特有的配置, 只需要将上面配置文件的 lettuce 文字替换为 jedis 即可.
# 连接池最大连接数(使用负值表示没有限制) 默认
spring.redis.jedis.pool.max-active=
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -
spring.redis.jedis.pool.max-wait=-
# 连接池中的最大空闲连接 默认
spring.redis.jedis.pool.max-idle=
# 连接池中的最小空闲连接 默认
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
============================
SessionConfig.java 文件
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600)
public class SessionConfig {
} //@Configuration
//@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600)
//public class SessionConfig {
// @Bean
// public RedisTemplate<Object, Object> sessionRedisTemplate(RedisConnectionFactory connectionFactory) {
// RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
// template.setKeySerializer(new StringRedisSerializer());
// template.setHashKeySerializer(new GenericJackson2JsonRedisSerializer());
// template.setConnectionFactory(connectionFactory);
// return template;
// }
//}
SesionConfig.java 是一个空的类, 该类其实并不是必需的, 必需的其实是@EnableRedisHttpSession注解, 我们可以将 @EnableRedisHttpSession 注解直接加到主程序类, 这样就可以省掉SesionConfig.java .
加上@EnableRedisHttpSession 注解后, SpringBoot程序在Servlet container 初始化时, 会创建一个 springSessionRepositoryFilter bean, 其实就是一个Filter, 该Fiber负责用 Spring Session替换默认的HttpSession实现.
============================
增加一个 HelloworldController.java文件
============================
@Controller
@RequestMapping("/test")
public class HelloworldController {
@RequestMapping("/set")
@ResponseBody
public String set(HttpServletRequest req) {
HttpSession session=req.getSession();
session.setAttribute("testKey", "testValue");
return "已经设置session:testKey=testValue, SessionId:"+session.getId();
} @RequestMapping("/query")
@ResponseBody
public Object query(HttpServletRequest req) {
HttpSession session=req.getSession();
Map<String, Object> map = new HashMap<String, Object>();
map.put("SessionId", session.getId());
map.put("testKey", session.getAttribute("testKey"));
return map;
}
}
============================
测试
============================
测试方法很简单, 使用同一个浏览器先后访问两个应用服务器, 如果能获得同一个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的更多相关文章
- SpringBoot,Security4, redis共享session,分布式SESSION并发控制,同账号只能登录一次
由于集成了spring session ,redis 共享session,导致SpringSecurity单节点的session并发控制失效, springSession 号称 无缝整合httpses ...
- SpringBoot+Shiro+Redis共享Session入门小栗子
在单机版的Springboot+Shiro的基础上,这次实现共享Session. 这里没有自己写RedisManager.SessionDAO.用的 crazycake 写的开源插件 pom.xml ...
- SpringBoot SpringSession redis 共享 SESSION
号称无缝整合httpsession 共享, 但注意如果存在第三方框架,例如SESSION并发控制,这个是需要自己重写session名单的. 关于redis session 共享 的session并发控 ...
- linux下实现redis共享session的tomcat集群
为了实现主域名与子域名的下不同的产品间一次登录,到处访问的效果,因此采用rediss实现tomcat的集群效果.基于redis能够异步讲缓存内容固化到磁盘上,从而当服务器意外重启后,仍然能够让sess ...
- Nginx+tomcat集群使用redis共享session
一 :nginx负载均衡 当Tomcat当做独立的Servlet容器来运行时,可看做是能运行Java Servlet的独立Web服务器. 此外 Tomcat还可以作为其他Web服务器进程内或者进程外的 ...
- Tomcat7.0.99集群使用Redis共享session方案
以前配置过给予多播的session共享方案,这回再配置一个redis共享session的. 先小小的炫耀一下: 相信大家要做Tomcat+Redis+session配置,遇到的头号麻烦就是编译的tom ...
- Spring Boot 使用 Redis 共享 Session 代码示例
参考资料 博客:spring boot + redis 实现session共享 1. 新建 Maven 工程 我新建 spring-boot-session-redis maven 工程 2. 引入 ...
- SpringBoot使用Redis共享用户session信息
SpringBoot引入Redis依赖: <dependency> <groupId>org.springframework.boot</groupId> < ...
- springboot整合redis存放session
y进入maven依赖: <!--spring boot 与redis应用基本环境配置 --> <dependency> <groupId>org.springfra ...
随机推荐
- Hdoj 1050.Moving Tables 题解
Problem Description The famous ACM (Advanced Computer Maker) Company has rented a floor of a buildin ...
- 每天一个linux命令(02):route命令
route命令用来显示并设置Linux内核中的网络路由表,route命令设置的路由主要是静态路由.要实现两个不同的子网之间的通信,需要一台连接两个网络的路由器,或者同时位于两个网络的网关来实现. 在L ...
- 逆向并查集 HYSBZ1015星球大战starwar
星球大战starwar HYSBZ - 1015 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系 ...
- [ZJOI2006]超级麻将(可行性dp)
题目描述 要判断某人是否胡牌,显然一个弱智的算法就行了,某中学信息学小组超级麻将迷想了想,决定将普通麻将改造成超级麻将. 所谓超级麻将没有了砣.索.万的区分,每种牌上的数字可以是1~100,而每种数字 ...
- 通俗讲解MOSFET
一位工程师曾经对我讲,他从来不看MOSFET数据表的第一页,因为“实用”的信息只在第二页以后才出现.事实上,MOSFET数据表上的每一页都包含有对设计者非常有价值的信息.但人们不是总能搞得清楚该如何解 ...
- thinkphp5 如何监听sql?
第一步 在database配置文件中开启 // 是否需要进行SQL性能分析'sql_explain' => true, 第二步 在需要测试的sql前,使用以下demo Db::listen(fu ...
- 洛谷P1173 [NOI2016]网格
这个码量绝对是业界大毒瘤...... 300行,6.5k,烦的要死...... 题意:给你一个网格图,里面有0或1.你需要把一些0换成1使得存在某两个0不四联通.输出最小的换的数量.无解-1. n,m ...
- A1146. Topological Order
This is a problem given in the Graduate Entrance Exam in 2018: Which of the following is NOT a topol ...
- (转)git stash使用
使用情形 综合下网上的介绍和资料,git stash(git储藏)可用于以下情形: 发现有一个类是多余的,想删掉它又担心以后需要查看它的代码,想保存它但又不想增加一个脏的提交.这时就可以考虑git s ...
- 【洛谷P2142 高精度减法】
题目描述 高精度减法 输入输出格式 输入格式: 两个整数a,b(第二个可能比第一个大) 输出格式: 结果(是负数要输出负号) 输入输出样例 输入样例#1: 复制 2 1 输出样例#1: 复制 1 说明 ...