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的更多相关文章

  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. 【BZOJ5211】[ZJOI2018]线图(树哈希,动态规划)

    [BZOJ5211][ZJOI2018]线图(树哈希,动态规划) 题面 BZOJ 洛谷 题解 吉老师的题目是真的神仙啊. 去年去现场这题似乎骗了\(20\)分就滚粗了? 首先\(k=2\)直接算\(k ...

  2. 【LOJ#6072】苹果树(矩阵树定理,折半搜索,容斥)

    [LOJ#6072]苹果树(矩阵树定理,折半搜索,容斥) 题面 LOJ 题解 emmmm,这题似乎猫讲过一次... 显然先\(meet-in-the-middle\)搜索一下对于每个有用的苹果数量,满 ...

  3. Luogu P5316 【恋恋的数学题】

    是个神仙题 就三种情况,分类讨论. \(k=2\): 因为保证有解,所以直接输出即可. \(k=3\): 由于对应情况可以枚举全排列寻找,所以在此只考虑顺序对应时的情况,不妨设六个数分别为\(g_{a ...

  4. 解决win10“cmd自动弹出一闪而过”问题的方法

    1.禁用CMD win+Q gpedit 打开组策略 用户配置--管理模板--系统--阻止访问命令提示符--已启用. 2.启用PowerShell PS:需要使用CMD时可用powershell代替: ...

  5. java实现sftp客户端上传文件以及文件夹的功能

    1.依赖的jar文件 jsch-0.1.53.jar 2.登录方式有密码登录,和密匙登录 代码: 主函数: import java.util.Properties; import com.cloudp ...

  6. WebClient请求接口,get和post方法

    1,get方式 string URI = "url"; //实例化 WebClient client = new WebClient(); // client.UseDefault ...

  7. 利用selenium并使用gevent爬取动态网页数据

    首先要下载相应的库 gevent协程库:pip install gevent selenium模拟浏览器访问库:pip install selenium selenium库相应驱动配置  https: ...

  8. (转)深入理解Java注解类型(@Annotation)

    背景:在面试时候问过关于注解的问题,工作中也用到过该java的特性,但是也没有深入的了解. 秒懂,Java 注解 (Annotation)你可以这样学 ps:注解最通俗易懂的解释 注解是一系列元数据, ...

  9. 用标准C编写COM dll

    参考资料: 用标准C编写COM(一)COM in plain C,Part1 (http://blog.csdn.net/wangqiulin123456/article/details/809235 ...

  10. Java 实例 - 如何执行指定class文件目录(classpath) Java 实例 J

    Java 实例 - 如何执行指定class文件目录(classpath)  Java 实例 如果我们 Java 编译后的class文件不在当前目录,我们可以使用 -classpath 来指定class ...