首页 > 数据库 >Springboot 开发 -- Redis实现分布式Session

Springboot 开发 -- Redis实现分布式Session

时间:2024-06-08 19:04:50浏览次数:34  
标签:session redis Springboot -- Spring Redis Session 序列化

一、引言

在微服务架构和分布式系统中,会话管理(Session Management)成为了一个挑战。传统的基于Servlet容器的会话管理方式在分布式环境下无法有效工作,因为用户请求可能会被分发到不同的服务器上,导致会话数据无法共享。为了解决这个问题,Spring Session提供了一种基于外部存储(如Redis)的会话管理方式,使得会话数据可以在多个服务器之间共享。

二、Spring Session原理

  • 替换HttpSession:Spring Session通过将Servlet容器实现的HttpSession替换为Spring Session,实现了会话数据的外部存储。这样,无论用户请求被分发到哪个服务器,都可以从外部存储中获取到相同的会话数据。
  • 配置类:Spring Session提供了几个关键的配置类,如RedisHttpSessionConfigurationSpringHttpSessionConfiguration用于配置Redis作为会话数据的存储后端
  • SessionRepositoryFilter:SessionRepositoryFilter是Spring Session的核心组件之一,它负责在请求处理之前和之后与会话存储进行交互,以确保会话数据的正确加载和保存

三、如何用 Redis 实现分布式 Session?

在分布式系统中,通常会将 Session 存储在 Redis 中来实现 分布式 Session,这样就可以在多台服务器之间共享 Session 数据。实现分布式Session通常使用Redis的Hash结构:

  1. 用户登录:当用户成功登录后,服务端生成一个唯一的 Session ID(通常是一个随机字符串,如 UUID)。

  2. 存储 Session:将用户的会话信息(如用户ID、权限信息等)与 Session ID 关联,并存储在 Redis 中。Redis 使用 Hash 结构来存储这些数据,其中 Session ID 作为 Hash 的 key,用户的会话信息作为 Hash 的 value。

  3. 设置 Cookie:将 Session ID 通过 Cookie 发送到客户端浏览器。这样,客户端在每次请求时都会携带这个 Cookie。

  4. 请求处理:在客户端的每次请求中,服务端都会检查 Cookie 中的 Session ID。服务端使用这个 ID 从 Redis 中检索对应的 Session 数据。

  5. 认证与授权:通过检索到的 Session 数据,服务端可以验证用户的身份,并根据用户的会话信息进行授权。

Session 过期:设置 Session 的过期时间,当用户长时间不活动或者显式退出登录时,服务端会从 Redis 中删除对应的 Session 数据。

四、实战步骤

1. 添加依赖:

在Spring Boot项目中,通过添加spring-boot-starter-data-redis和spring-session-data-redis的依赖,引入Spring Session和Redis的支持。

<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-data-redis</artifactId>  
</dependency>  

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

2. application.yml中配置

server:  
  servlet:  
    session:  
      timeout: 3600 # session 有效期 1小时
  
spring:  
  session:  
    store-type: redis # 使用 Redis 存储会话  
    # 其他 Spring Session 相关配置  
  	redis:
  	  namespace: myapplication:session #Redis Session 存储的命名空间

# Redis 配置  
spring:  
  redis:  
    host: 127.0.0.1  
    port: 6379  
    # 其他 Redis 相关配置

3. 启用Spring Session:

@EnableRedisHttpSession 是 Spring Session 的一个注解,用于在 Spring Boot 应用程序中启用基于 Redis 的 HTTP Session 管理。它会创建一个名为 springSessionRepositoryFilter 的 Bean,这个 Bean 负责替换默认的 HTTP Session 实现。

在Spring Boot的主类或配置类添加@EnableRedisHttpSession注解,启用Spring Session对HttpSession的替换。

  • 方式一:启动类配置
@SpringBootApplication  
@EnableRedisHttpSession  
public class MyApplication {  
    public static void main(String[] args) {  
        SpringApplication.run(MyApplication.class, args);  
    }  
}
  • 方式二:增加 RedisSessionConfig 配置类
@Configuration
@EnableRedisHttpSession(redisNamespace = "myapplication:session", maxInactiveIntervalInSeconds = 3600, redisFlushMode = RedisFlushMode.IMMEDIATE)
public class RedisSessionConfig {

    @Bean
    public CookieSerializer cookieSerializer() {
        DefaultCookieSerializer defaultCookieSerializer = new DefaultCookieSerializer();
        //cookie名字
        defaultCookieSerializer.setCookieName("myapplication-sessionId");
        defaultCookieSerializer.setUseHttpOnlyCookie(true);
        return defaultCookieSerializer;
    }
}

@EnableRedisHttpSession 参数说明:

  • maxInactiveIntervalInSeconds: 设置 Session 的最大非活动时间(秒)。默认为 1800 秒(30 分钟)

  • redisNamespace: 定义存储在 Redis 中的 Session 数据的命名空间。默认为 "spring:session"

  • redisFlushMode: 定义 Session 数据刷新到 Redis 的模式。默认为 RedisFlushMode.ON_SAVE,表示每次调用 SessionRepository 的 save 方法时,Session 数据都会同步刷新到 Redis。其他可选的模式包括 RedisFlushMode.IMMEDIATE(立即刷新)和 RedisFlushMode.NONE(不刷新)

  • cleanupCron: 定义一个 cron 表达式,用于设置清理 Redis 中过期 Session 的计划。默认为每分钟执行一次

或通过 配置文件配置:

# HTTP Session 过期时间(秒)
server.servlet.session.timeout=1800

# Redis Session 存储的命名空间
spring.session.redis.namespace=spring:session

4. 配置 Redis 序列化 存储

以下是一个配置 RedisTemplate 以使用 JSON 序列化的示例,这里我们使用 Jackson2JsonRedisSerializer 作为序列化器:

import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.data.redis.connection.RedisConnectionFactory;  
import org.springframework.data.redis.core.RedisTemplate;  
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;  
import org.springframework.data.redis.serializer.StringRedisSerializer;  
  
import com.fasterxml.jackson.annotation.JsonAutoDetect;  
import com.fasterxml.jackson.annotation.PropertyAccessor;  
import com.fasterxml.jackson.databind.ObjectMapper;  
  
@Configuration  
public class RedisConfig {  
  
    @Bean
	public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory factory) {
		RedisTemplate<Object, Object> template = new RedisTemplate<>();
		// 配置连接工厂
		template.setConnectionFactory(factory);

		//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
		Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);

		ObjectMapper om = new ObjectMapper();
		// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
		om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
		// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
		om.activateDefaultTyping( LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY);
		// 空字段不序列化
		om.setDefaultPropertyInclusion(JsonInclude.Include.NON_NULL);
		// 解决jackson2无法反序列化LocalDateTime的问题
		om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
		om.registerModule(new JavaTimeModule());

		jsonRedisSerializer.setObjectMapper(om);

		// 值采用json序列化
		template.setValueSerializer(jsonRedisSerializer);
		//使用StringRedisSerializer来序列化和反序列化redis的key值
		template.setKeySerializer(new StringRedisSerializer());

		//设置hash key 和value序列化模式
		template.setHashKeySerializer(new StringRedisSerializer());
		template.setHashValueSerializer(jsonRedisSerializer);
		template.afterPropertiesSet();

		return template;
	}
}

关于序列化 及 RedisTemplate 配置可参考 序列化与消息转换器

5. 使用HttpSession:

在Controller或Service中,使用HttpSession对象来存储和获取会话数据,Spring Session会自动处理会话数据的存储和加载。

标签:session,redis,Springboot,--,Spring,Redis,Session,序列化
From: https://blog.csdn.net/dazhong2012/article/details/139211048

相关文章

  • 【计算机毕业设计】springboot027网上点餐系统
    随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于网上点餐系统当然也不能排除在外,随着网络技术的不断成熟,带动了网上点餐系统,它彻底改变了过去传统的管理方式,不仅使服务管理难度变低了,还提升了管理的灵活性。这种个性化的平台特别......
  • 【计算机毕业设计】springboot030甘肃非物质文化网站的设计与开发
    现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本甘肃非物质文化网站就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,......
  • 【计算机毕业设计】springboot031教师工作量管理系统
    随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了教师工作量管理系统的开发全过程。通过分析教师工作量管理系统管理的不足,创建了一个计算机管理教师工作量管理系统的方案。文章介绍了教师工作量管理系统的系统分析部分,包括可......
  • 【计算机毕业设计】springboot032阿博图书馆管理系统
    随着社会的发展,计算机的优势和普及使得阿博图书馆管理系统的开发成为必需。阿博图书馆管理系统主要是借助计算机,通过对图书借阅等信息进行管理。减少管理员的工作,同时也方便广大用户对所需图书借阅信息的及时查询以及管理。阿博图书馆管理系统的开发过程中,采用B/S架构,主......
  • Python学习日记Day1
    目录一、Python的安装二、输出print()1,输出单变量后换行——print(*)2,连续输出多个变量不换行——print(*,*,*,*,*)用英文逗号分离3,使用ASCII码进行输出——借助chr()函数4,使用Unicode码进行输出——借助ord()函数 5,ASCII码与Unicode码的相互转换6,使用print()函数将内......
  • 什么是合格的产品经理
     1.什么是产品能够解决某个问题的东西就是产品。分为有形的产品(水杯、手表),无形的产品(软件、网页)。2.什么是产品经理想清楚产品如何设计的人就是产品经理。3.产品经理需要关注的核心问题(1)用户、场景、需求面对问题时想清楚:谁在什么情况下遇到了什么事。用户在什么场......
  • centos 环境 nginx 安装及常用命令简介
    一、引言Nginx是一个高性能的HTTP和反向代理服务器,因其卓越的性能、丰富的功能集、简单的配置和低资源消耗而广受欢迎。本文将详细介绍如何在CentOS系统中安装Nginx,并简要介绍一些常用的Nginx命令。二、在CentOS中安装Nginx1.先检查服务器GCC环境是否安装gcc-v2.......
  • 【Linux】进程3——PID/PPID,父进程,子进程
    在讲父子进程之前,我们接着上面那篇继续讲1.查看进程mycode.cmakefile我们在zs_108直接编译mycode.c,直接运行,然后我们转换另一个账号来查看这个进程我们可以通过ps指令来查看进程  我们就会好奇了,第二行是什么?我们查的是第一行的啊那个是指令的ps的进程PID有什......
  • 如何在CANoe中进行DoIP测试配置
    文章目录一、添加以太网网段信息二、诊断TP层配置1.配置诊断通道2.配置DoIP设置3.配置安全访问算子三、手动验证测试四、DoIP自动化脚本好好学习,多做笔记。以下是CANoe中DoIP的测试配置流程。一、添加以太网网段信息新建诊断DoIP测试网段,添加节点。在Simulation......
  • 怎么找到“天赋”?
    一定要输出自己擅长的内容,这样才能持续和长久。梁宁老师说过:“什么东西让你永远不爽,什么事情让你持续满足,这就是你的命运所在;能让你不厌其烦去做的事,就是你的天赋所在。怎么找到天赋?首先要看你对什么事敏感;其次,看你在做这件能引起你敏感的事时,是不是能让你获得满足;最后,看你......