springboot中redis的使用和分布式session共享问题

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 本文旨在解决分布式系统的session如何共享问题,大致思路:session放入redis。其他解决方案:持久化、放cache等都可以,但是自从有了redis,这完全可以变的简简单单。

本文旨在解决分布式系统的session如何共享问题,大致思路:session放入redis。其他解决方案:持久化、放cache等都可以,但是自从有了redis,这完全可以变的简简单单。
本文大致分两步:
1.springboot中如何使用redis。
2.redis如何解决session共享

pom依赖

       <!--redis配置开始-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>${spring-data-redis.version}</version>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>${jedis.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>
        <!--redis配置结束-->

添加redis配置类

该配置类同样可以配置缓存失效时间等。

package com.mos.quote.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

/**
 * @author Administrator
 */
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    @Bean
    public KeyGenerator KeyGenerator(){
        return (target, method, params) -> {
            StringBuilder sb = new StringBuilder();
            sb.append(target.getClass().getName());
            sb.append(method.getName());
            for (Object obj : params) {
                sb.append(obj.toString());
            }
            return sb.toString();
        };
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate(factory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    public CacheManager cacheManager(RedisTemplate<String,String> redisTemplate) {
        RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
        //设置缓存过期时间
        rcm.setDefaultExpiration(600000);
        return rcm;
    }
}

配置redis服务

# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=192.168.1.118
# Redis服务器连接端口
spring.redis.port=6381
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=0

单元测试

  1. set值(字符串)
    @Test
    public void put(){
        stringRedisTemplate.opsForValue().set("test001","test001");
        Assert.assertEquals("test001", stringRedisTemplate.opsForValue().get("test001"));
    }

往redis放一个key为test001、value为test001的值,然后查看redis

img_c2ca8e5ed322c144a8e3c8f322a395da.png
key=test001
  1. set值(object)
  @Test
    public void testObj() throws Exception {
        SysUser user=new SysUser();
        user.setId("123456");
        user.setName("张三");
        ValueOperations<String, SysUser> operations=redisTemplate.opsForValue();
        operations.set("user1", user);
        operations.set("user2", user,5, TimeUnit.SECONDS);
        Thread.sleep(6000);
        Assert.assertFalse(redisTemplate.hasKey("user2"));
    }

往redis分别放key为user1和user2的对象,user2设置5秒失效,线程等待6秒再完成,期望结果:redis中有user1,没有user2,bingo!!!

img_b8c739071eeaf6ee26c1ef83edec997b.png
ObjTest

解决session共享

使用spring-session-data-redis实现session共享,pom中引入该依赖(上文已添加),添加SessionConfig配置类。
对,没看错,只需要这个就够了。最长有效时间根据自己情况随意配置即可。

package com.mos.quote.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

/**
 * @author Administrator
 */
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3000)
public class SessionConfig {
}

测试

写一个简单Controller,如下

    @RequestMapping("testSessionTimeOut")
    public String testSessionTimeOut(String id,HttpSession session,Model model){
        Area area = areaService.getById(id);
        System.out.println("sessionId-------->"+session.getId());
        model.addAttribute("area",JSON.toJSONString(area));
        session.setAttribute("area",JSON.toJSONString(area));
        return "demo/test1";
    }

这里可以看到sessionId:

img_853fda718717f65c650b4a25c4570d6d.png
sessionId

看redis中,可以看到失效时间,sessionId等

img_1f1b73e964922ed0b28e9dc4354a7f55.png
sessionId

共享session

另外找一个机器,照着这个配置再来一遍,自动启用session共享,因为sessionId都存在了同一个redis中。奏是这么简单。挽起袖子开始干吧。

目录
相关文章
|
27天前
|
NoSQL Java 调度
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
分布式锁是分布式系统中用于同步多节点访问共享资源的机制,防止并发操作带来的冲突。本文介绍了基于Spring Boot和Redis实现分布式锁的技术方案,涵盖锁的获取与释放、Redis配置、服务调度及多实例运行等内容,通过Docker Compose搭建环境,验证了锁的有效性与互斥特性。
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
|
5月前
|
监控 Java 调度
SpringBoot中@Scheduled和Quartz的区别是什么?分布式定时任务框架选型实战
本文对比分析了SpringBoot中的`@Scheduled`与Quartz定时任务框架。`@Scheduled`轻量易用,适合单机简单场景,但存在多实例重复执行、无持久化等缺陷;Quartz功能强大,支持分布式调度、任务持久化、动态调整和失败重试,适用于复杂企业级需求。文章通过特性对比、代码示例及常见问题解答,帮助开发者理解两者差异,合理选择方案。记住口诀:单机简单用注解,多节点上Quartz;若是任务要可靠,持久化配置不能少。
511 4
|
8月前
|
NoSQL Java Redis
Springboot使用Redis实现分布式锁
通过这些步骤和示例,您可以系统地了解如何在Spring Boot中使用Redis实现分布式锁,并在实际项目中应用。希望这些内容对您的学习和工作有所帮助。
714 83
|
4月前
|
机器学习/深度学习 数据采集 人机交互
springboot+redis互联网医院智能导诊系统源码,基于医疗大模型、知识图谱、人机交互方式实现
智能导诊系统基于医疗大模型、知识图谱与人机交互技术,解决患者“知症不知病”“挂错号”等问题。通过多模态交互(语音、文字、图片等)收集病情信息,结合医学知识图谱和深度推理,实现精准的科室推荐和分级诊疗引导。系统支持基于规则模板和数据模型两种开发原理:前者依赖人工设定症状-科室规则,后者通过机器学习或深度学习分析问诊数据。其特点包括快速病情收集、智能病症关联推理、最佳就医推荐、分级导流以及与院内平台联动,提升患者就诊效率和服务体验。技术架构采用 SpringBoot+Redis+MyBatis Plus+MySQL+RocketMQ,确保高效稳定运行。
280 0
|
7月前
|
存储 Java 文件存储
🗄️Spring Boot 3 整合 MinIO 实现分布式文件存储
本文介绍了如何基于Spring Boot 3和MinIO实现分布式文件存储。随着应用规模扩大,传统的单机文件存储方案难以应对大规模数据和高并发访问,分布式文件存储系统成为更好的选择。文章详细讲解了MinIO的安装、配置及与Spring Boot的整合步骤,包括Docker部署、MinIO控制台操作、Spring Boot项目中的依赖引入、配置类编写及工具类封装等内容。最后通过一个上传头像的接口示例展示了具体的开发和测试过程,强调了将API操作封装成通用工具类以提高代码复用性和可维护性的重要性。
1315 7
🗄️Spring Boot 3 整合 MinIO 实现分布式文件存储
|
9月前
基于springboot+thymeleaf+Redis仿知乎网站问答项目源码
基于springboot+thymeleaf+Redis仿知乎网站问答项目源码
265 36
|
存储 SQL 消息中间件
springboot整合redis
redis是一个支持key-value的数据库,数据全部在内存中处理,在在一定时间间隔中将数据固化到磁盘。因为是内存操作,所以速度特别快。(这里我们主要介绍redis作为缓存使用)
263 0
springboot整合redis
|
存储 缓存 NoSQL
SpringBoot整合Redis
SpringBoot整合Redis
517 0
SpringBoot整合Redis
|
NoSQL Redis 存储
springboot整合redis
直接上代码吧 1.首先pom中加入 org.springframework.boot spring-boot-starter-web org.
1324 0

热门文章

最新文章