文章目录

  • 快速入门 Spring Session + Redis
    • 官网指导
    • Demo
    • pom 依赖
    • 配置文件
    • 配置类RedisHttpSessionConfiguration
    • Redis中的session数据解析
  • 附 其他相关类
    • BaseController
    • 统一返回结果相关的Code
  • Jedis的POM依赖及配置


快速入门 Spring Session + Redis

官网指导

https://spring.io/projects/spring-session-data-redis#samples

我们就用spring boot 来演示下吧

Demo

pom 依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>boot2</artifactId><groupId>com.artisan</groupId><version>0.0.1-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>springsession</artifactId><dependencies><!-- 实现对 Spring MVC 的自动化配置 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- redis  lettuce 需要使用--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency><!-- 实现对 Spring Session 使用 Redis 作为数据源的自动化配置 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- 实现对 Spring Data Redis 的自动化配置 --><dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

配置文件

server:port: 8888spring:redis:host: 127.0.0.1port: 6379password: # Redis密码timeout: 5000mslettuce:pool:max-active: 8max-wait: -1msmax-idle: 8min-idle: 0session:store-type: redis
  • max-active: 8 # 连接池最大连接数,默认为 8 。使用负数表示没有限制。

  • max-idle: 8 # 默认连接数最大空闲的连接数,默认为 8 。使用负数表示没有限制。

  • min-idle: 0 # 默认连接池最小空闲的连接数,默认为 0 。允许设置 0 和 正数。

  • max-wait: -1 # 连接池最大阻塞等待时间,单位:毫秒。默认为 -1 ,表示不限制。

  • session: store-type: redis 指定存储类型


配置类RedisHttpSessionConfiguration

package com.artisan.config;import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;/*** @author 小工匠* @version 1.0* @description: TODO* @date 2021/2/16 14:12* @mark: show me the code , change the world*/
@Configuration
@EnableRedisHttpSession
public class RedisHttpSessionConfiguration {@Bean(name = "springSessionDefaultRedisSerializer")public RedisSerializer springSessionDefaultRedisSerializer() {return RedisSerializer.json();}
}

添加 @EnableRedisHttpSession 注解,开启自动化配置 Spring Session 使用 Redis 作为数据 。

我们来下 EnableRedisHttpSession 注解

  • maxInactiveIntervalInSeconds 属性,Session 不活跃后的过期时间,默认为 1800 秒。

  • redisNamespace 属性,在 Redis 的 key 的统一前缀,默认为 “spring:session” 。

  • flushMode 属性,Redis 会话刷新模式(RedisFlushMode)。支持两种,默认为RedisFlushMode.ON_SAVE

    RedisFlushMode.ON_SAVE ,在请求执行完成时,统一写入 Redis 存储。
    RedisFlushMode.IMMEDIATE ,在每次修改 Session 时,立即写入 Redis 存储。

  • cleanupCron 属性,清理 Redis Session 会话过期的任务执行 CRON 表达式,默认为 "0 * * * * *" 每分钟执行一次。虽然Redis 自带了 key 的过期,但是惰性删除策略,实际过期的 Session 还在 Redis 中占用内存。所以,Spring Session 通过定时任务,删除 Redis 中过期的 Session ,尽快释放 Redis 的内存。

默认情况下,采用 Java 自带的序列化方式 ,可读性很差。 所以在 springSessionDefaultRedisSerializer() 方法,定义了一个 Bean 名字为 springSessionDefaultRedisSerializer的 RedisSerializer Bean ,采用 JSON 序列化方式 。


好了,截止到目前,核心的框架已经搭建起来了,我们来测试下

package com.artisan.controller;import com.artisan.common.CommonResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;/*** @author 小工匠* @version 1.0* @description: TODO* @date 2021/2/16 14:42* @mark: show me the code , change the world*/
@RestController
public class ArtisanController  extends BaseController {@GetMapping("/mockSet")public CommonResult set(@RequestParam("key") String key, @RequestParam("value") String value) {getHttpSession().setAttribute(key, value);return CommonResult.success("成功模拟登录");}@GetMapping("/mockGet") public CommonResult get(@RequestParam("key") String key) {return CommonResult.success( getHttpSession().getAttribute(key));}}

启动测试类,走一波

package com.artisan;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringSeesionDemoApplication {public static void main(String[] args) {SpringApplication.run(SpringSeesionDemoApplication.class, args);}}

访问 http://localhost:8888/mockSet?key=artisan &value=avalue

http://localhost:8888/mockGet?key=artisan


Redis中的session数据解析

127.0.0.1:0>keys *1)  "spring:session:sessions:expires:e0dd90b9-9551-4e8a-9609-cde0758b88c2"2)  "spring:session:sessions:e0dd90b9-9551-4e8a-9609-cde0758b88c2"3)  "spring:session:expirations:1613470560000"

每一个 Session 对应 Redis 二个 key-value 键值对

  • 开头:以 spring:session 开头,可以通过 @EnableRedisHttpSession 注解的 redisNamespace 属性配置。
  • 结尾:以对应 Session 的 sessionid 结尾。
  • 中间:中间分别是 "session"、"expirations"、sessions:expires

一般情况下,只需要关注中间为 session 的 key-value 键值对即可,它负责真正存储 Session 数据

127.0.0.1:0>hgetall spring:session:sessions:ab7d40d8-cd3d-49d7-8b3a-d1ae71d409351)  "lastAccessedTime"  # 最后访问时间2)  "1613469344975"3)  "maxInactiveInterval" # Session 允许最大不活跃时长,单位:秒。4)  "1800"5)  "creationTime"   # 创建时间6)  "1613469342207"7)  "sessionAttr:artisan" # 设置的属性值8)  ""avalue""
127.0.0.1:0>

对于中间为 sessions:expiresexpirations的两个来说,主要为了实现主动删除 Redis 过期的 Session 会话,解决 Redis 惰性删除的问题。

spring:session:expirations:{时间戳},是为了获得每分钟需要过期的 sessionid 集合,即 {时间戳} 是每分钟的时间戳


附 其他相关类

BaseController

package com.artisan.controller;import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;public class BaseController  {public HttpServletRequest getRequest(){return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();}public HttpServletResponse getResponse(){return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();}public HttpSession getHttpSession(){return getRequest().getSession();}}

统一返回结果相关的Code

【IErrorCode 】

package com.artisan.common;public interface IErrorCode {long getCode();String getMessage();
}

【ResultCode 】

package com.artisan.common;public enum ResultCode implements IErrorCode {SUCCESS(200, "操作成功"),FAILED(500, "操作失败"),VALIDATE_FAILED(404, "参数检验失败"),UNAUTHORIZED(401, "暂未登录或token已经过期"),FORBIDDEN(403, "没有相关权限");private long code;private String message;private ResultCode(long code, String message) {this.code = code;this.message = message;}public long getCode() {return code;}public String getMessage() {return message;}
}

【CommonResult】

package com.artisan.common;public class CommonResult<T> {private long code;private String message;private T data;protected CommonResult() {}protected CommonResult(long code, String message, T data) {this.code = code;this.message = message;this.data = data;}/*** 成功返回结果** @param data 获取的数据*/public static <T> CommonResult<T> success(T data) {return new CommonResult<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);}/*** 成功返回结果** @param data 获取的数据* @param  message 提示信息*/public static <T> CommonResult<T> success(T data, String message) {return new CommonResult<T>(ResultCode.SUCCESS.getCode(), message, data);}/*** 失败返回结果* @param errorCode 错误码*/public static <T> CommonResult<T> failed(IErrorCode errorCode) {return new CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null);}/*** 失败返回结果* @param message 提示信息*/public static <T> CommonResult<T> failed(String message) {return new CommonResult<T>(ResultCode.FAILED.getCode(), message, null);}/*** 失败返回结果*/public static <T> CommonResult<T> failed() {return failed(ResultCode.FAILED);}/*** 参数验证失败返回结果*/public static <T> CommonResult<T> validateFailed() {return failed(ResultCode.VALIDATE_FAILED);}/*** 参数验证失败返回结果* @param message 提示信息*/public static <T> CommonResult<T> validateFailed(String message) {return new CommonResult<T>(ResultCode.VALIDATE_FAILED.getCode(), message, null);}/*** 未登录返回结果*/public static <T> CommonResult<T> unauthorized(T data) {return new CommonResult<T>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data);}/*** 未授权返回结果*/public static <T> CommonResult<T> forbidden(T data) {return new CommonResult<T>(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data);}/*** 请求异常返回结果#add by yangguo*/public static <T> CommonResult<T> badResponse(IErrorCode errorCode) {return new CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null);}public long getCode() {return code;}public void setCode(long code) {this.code = code;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public T getData() {return data;}public void setData(T data) {this.data = data;}
}

Jedis的POM依赖及配置

Spring Boot 2 以上默认使用lettuce作为redis的客户端,如果想要用jedis ,我这里也给大家准备了一份,请参考

  <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusions><!-- 去掉对 Lettuce 的依赖, Spring Boot 优先使用 Lettuce 作为 Redis 客户端 --><exclusion><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId></exclusion></exclusions></dependency><!-- 引入 Jedis 的依赖 --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency></dependencies>
spring:# 对应 RedisProperties 类redis:host: 127.0.0.1port: 6379password: # Redis 服务器密码,默认为空。生产中,一定要设置 Redis 密码!database: 0 # Redis 数据库号,默认为 0 。timeout: 0 # Redis 连接超时时间,单位:毫秒。# 对应 RedisProperties.Jedis 内部类jedis:pool:max-active: 8 # 连接池最大连接数,默认为 8 。使用负数表示没有限制。max-idle: 8 # 默认连接数最大空闲的连接数,默认为 8 。使用负数表示没有限制。min-idle: 0 # 默认连接池最小空闲的连接数,默认为 0 。允许设置 0 和 正数。max-wait: -1 # 连接池最大阻塞等待时间,单位:毫秒。默认为 -1 ,表示不限制。

Spring Session - 使用Spring Session从零到一构建分布式session相关推荐

  1. Tornado 自定义session,与一致性哈希 ,基于redis 构建分布式 session框架

    Tornado 自定义session,与一致性哈希 ,基于redis 构建分布式 session import tornado.ioloopimport tornado.webfrom myhash ...

  2. 170222、使用Spring Session和Redis解决分布式Session跨域共享问题

    使用Spring Session和Redis解决分布式Session跨域共享问题 原创 2017-02-27 徐刘根 Java后端技术 前言 对于分布式使用Nginx+Tomcat实现负载均衡,最常用 ...

  3. 使用Spring Session和Redis解决分布式Session跨域共享问题

    大家可以关注一下公众号"Java架构师秘籍" 前言 对于分布式使用Nginx+Tomcat实现负载均衡,最常用的均衡算法有IP_Hash.轮训.根据权重.随机等.不管对于哪一种负载 ...

  4. 基于Spring Session实现JIM分布式Session

    基于Spring Session实现JIM分布式Session 前引 在实际项目中,应用程序经常会以集群方式部署线上,一般来说无状态的应用程序是理想的部署方式,一旦应用程序拥有状态(比如Session ...

  5. 使用springSession完成分布式session

    系列文章目录 文章目录 系列文章目录 使用springSession完成分布式session 使用springSession完成分布式session 原文链接 https://zhhll.icu/20 ...

  6. 分布式Session一致性概述

    分布式Session一致性问题 什么是SessionSession 是客户端与服务器通讯会话技术, 比如浏览器登陆.记录整个浏览会话信息 分布式SESSION一致性的问题,分布式SESSION到底如何 ...

  7. Spring Boot(十一)Redis集成从Docker安装到分布式Session共享

    2019独角兽企业重金招聘Python工程师标准>>> 一.简介 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并 ...

  8. session传递参数_分布式 Session 之 Spring Session 架构与设计

    作者 | 李增光 杏仁后端工程师.「只有变秃,才能变强!」 ​前言 开始进行 Web 开发时,我们可能会遇到这样的情况,当服务器重启之后,之前的登录状态会失效需要重新登录.又或者你的应用程序部署了不止 ...

  9. [译]Spring Session 与 Spring Security

    原文:http://docs.spring.io/spring-session/docs/current-SNAPSHOT/reference/html5/guides/security.html 本 ...

最新文章

  1. 软件测试-PR录制脚本程序ie的时候闪退
  2. 神策数据:从技术视角看,如何更多、更好、更快地实施A/B试验
  3. 二值图像的距离变换研究
  4. Kubeflow使用Kubernetes进行机器学习GPU分布式训练
  5. java setlayout_Java Button.setLayoutX方法代码示例
  6. Oracle中的sequence对象
  7. Codeforces Round #197 (Div. 2): D. Xenia and Bit Operations(线段树)
  8. cloudare mysql 密码修改_CentOS7.3 LAMP环境搭建私有云NextCloud过程记录
  9. 伟大的通信使者——JSON(JavaScript版本)
  10. javascript_core之正则、Math、Date
  11. 规范JavaScript注释
  12. 软件开发生命周期的五个阶段
  13. truncate table(截断表)
  14. Qt之调用Windows图片查看器预览图片
  15. 诛仙斩龙墨雪服务器怎么找不到了,《诛仙3》5月13日服务器数据互通公告
  16. 华为确定发布鸿蒙的时间了吗,Mate40系列首发,华为鸿蒙OS手机版发布时间确定...
  17. OBS Studio安装教程以及录制等详细配置
  18. Unity FairyGUI(十二)
  19. DEM+谷歌地球取点工具获取场地地形矢量数据
  20. 2006电子商务大盘点

热门文章

  1. 下如何画出频率瀑布图_用maftools一行代码画出瀑布图
  2. Oracle的job(定时执行存储过程)
  3. python sin(x)/x 图像
  4. ubuntu 安装 anaconda
  5. Hierarchical Attention Networks for Document Classification 阅读笔记
  6. osmnx 补充笔记:get_edge_colors_by_attr get_node_colors_by_attr
  7. 机器学习笔记:Adagrad
  8. Python应用实战案例-Python实现K线图绘制
  9. MATLAB从入门到精通-新增返回数组高、宽数字特征的全新方式
  10. Linux疑难杂症解决方案100篇(九)-SHELL编程正则表达式