☰
Spring Boot整合Redis实战:缓存、分布式锁与问题排查
2026/9/26 4:41:03 网站建设 项目流程

做Java后端的朋友应该都有过这种体会:Spring Boot项目里除了MySQL,最常打交道的中间件就是Redis了。不管是拿它做缓存扛高并发,还是用它做分布式锁解决资源竞争,哪怕是存个验证码、做排行榜,Redis总能在项目里找到自己的位置。“Spring Boot整合Redis”听起来像是老生常谈,但真正动手做的时候,你会遇到序列化乱码、连接超时、缓存穿透、key设计不合理、数据对不上等一系列问题。我这些年在前端后端项目里来回折腾,踩过的坑不少,也沉淀出了一些可复用的实践套路。这篇文章就把Spring Boot整合Redis的完整步骤、核心原理、常见场景和排障经验一次性讲清楚,希望能帮你在自己的项目里少走弯路。

这篇内容适合正在做毕业设计、课程设计的同学,也适合刚入职需要接手老项目的初级开发,以及那些想系统梳理Redis使用方式的工程师。我会从环境准备、依赖集成、序列化配置、缓存场景、分布式锁到问题排查,按实际操作顺序展开,尽量做到“按着做就能跑起来”。

1. 整体设计思路:先搞清楚Redis在你的项目里到底扮演什么角色

1.1 为什么几乎所有Spring Boot项目都绕不开Redis

Redis本质上是一个基于内存的键值存储系统,读写速度可以达到微秒级别,单机QPS轻松破十万。相比MySQL这类磁盘型数据库,Redis天然适合承载“读多写少”“高频访问”“短时效数据”这类流量模型。Spring Boot作为目前最主流的Java快速开发框架,提供了spring-boot-starter-data-redis这个官方启动器,把Redis的操作封装得极其简单——你只需要在配置文件里填几个参数,注入一个RedisTemplate,就能直接调用它的API完成各种业务操作。

我见过很多项目,最开始数据量不大、并发不高,所有热点数据都直接查MySQL。但一旦用户量涨上来,SQL慢查询就会开始报错,数据库连接池也会被占满。这时候最简单的优化方式就是把热点数据放进Redis,用内存换时间。再往后,当项目从单机变成多实例部署,Session共享、分布式锁、接口幂等这些需求也会跟着出现,而这些恰恰都是Redis比较拿手的场景。可以说,在Java服务端技术栈里,Redis不是“要不要用”的问题,而是“怎么用更合理”的问题。

1.2 选型和前置思考:别急着写代码,先回答三个问题

我在帮一些初学朋友看代码时,发现很多人一上来就直接redisTemplate.opsForValue().set(key, value),结果到后面到处都是硬编码的key,缓存过期时间随意,甚至出现数据污染。其实整合Redis之前,先花一点时间想清楚三件事,之后会顺畅很多:

  • 数据类型选对了吗:Redis有String、Hash、List、Set、ZSet五大基本类型。缓存一个用户信息用String还是Hash?做排行榜用ZSet是不是更合适?统计UV用Set还是HyperLogLog?数据模型没想清楚,后面会出现大量中间代码。

  • 缓存边界在哪:哪些数据需要进Redis?缓存多大?过期时间多久?一致性要求多高?如果每一次修改都要求Redis和数据库完全同步,那是设计上出了问题,而不是代码不够努力。

  • 部署形态是什么:本地开发用单机Redis就行,但生产环境要考虑主从、哨兵或集群,这些都会影响配置方式和客户端选择。

把这些问题想清楚了,再去看Spring Boot怎么引入Redis,会发现所有步骤都是有逻辑的:依赖解决“用什么操作Redis”,配置解决“怎么连上Redis”,序列化解决“数据以什么形式存进去”,而后面的场景代码则回答“存进去以后拿来干什么”。

2. 环境准备:Redis安装与可视化客户端选型

2.1 本地开发环境的Redis安装(Windows与macOS实测)

很多教程默认你在Linux上装Redis,但实际情况是大量本地开发环境是Windows或macOS。Windows下装Redis最省事的方式是去GitHub上的tporadowski/redis项目下载免安装版或MSI安装包,它长期维护Windows原生移植版,版本跟得上Redis 5.x之后的主流功能。下载后直接解压,redis-server.exe就是服务端,双击启动即可。默认端口6379,启动后命令行会打印“Ready to accept connections tcp”,说明已经把服务拉起来了。为了操作方便,我建议把Redis目录加入系统PATH,这样你在任意目录都能执行redis-cli。

macOS下更简单,直接brew install redis,装完用brew services start redis命令设置成后台常驻,或者用redis-server /usr/local/etc/redis.conf手动拉起。这里提醒一句:启动后会占用当前终端窗口,开发时建议加daemonize yes配置或直接使用brew的services方式,省得你每次开终端都要重来一次。

2.2 生产环境推荐Docker部署,版本别乱选

线上部署我基本不会直接在宿主机上装Redis。Docker容器化最大的好处是环境隔离和快速迁移,而且官方镜像redis质量非常高,配置和版本清清楚楚。一条命令就能起一个单机Redis:

docker run -d --name redis \ -p 6379:6379 \ -v /data/redis/redis.conf:/etc/redis/redis.conf \ -v /data/redis/data:/data \ --restart=always \ redis:7.2-alpine \ redis-server /etc/redis/redis.conf

注意几个细节。第一,版本标签不要用latest,生产环境必须固定版本,我一般用7.0或7.2系列的alpine版本,镜像体积小,安全更新及时。第二,宿主机目录挂载时,redis.conf要提前准备好,否则容器把目录当成文件会直接报错。第三,内存持久化配置要在conf里开启,默认appendonly no,如果不设置,Redis重启后数据就全丢了,这在生产环境是不能接受的。

如果你的场景是“docker安装redis主从”或者更复杂的哨兵集群,我建议先在一个节点上把单机跑熟,再复制出多个容器,配置好主从关系。主从配置并不复杂,从节点配置文件里加上replicaof 主节点IP 6379,主节点的数据就会自动同步到从节点。注意从节点默认是只读的,写入操作会被拒绝,这是正常现象。

2.3 可视化客户端:Redis Desktop Manager还是Another Redis Desktop Manager

命令行redis-cli固然强大,但日常开发和调试时,我还是建议装一个可视化客户端。市面上最出名的Redis Desktop Manager(RDM)前几年开始收费,社区版已经很旧了,新用户我不推荐。目前我更习惯用Another Redis Desktop Manager,开源免费,跨平台,UI流畅,功能也够用。

这个工具连接Redis很简单,填IP、端口、密码就能连上。它有几点功能特别实用:支持按正则扫描key,不用KEYS *就能批量处理;内置Terminal面板可以直接敲Redis命令;还可以查看内存分析、慢日志,这对后续排查Big Key问题很有帮助。如果你习惯用IDEA做开发,那Iedis或IDEA自带的database插件也可以连Redis,但功能不如独立客户端丰富,看个人习惯。

3. Spring Boot整合Redis核心步骤:依赖、配置与序列化

3.1 引入依赖与基础配置

Spring Boot整合Redis的核心依赖只有一个,在pom.xml里加入:

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

这个starter默认使用Lettuce客户端,是Spring官方推荐的,支持同步、异步和响应式三种模式,线程安全,配置合理。国内有些老项目还在用Jedis,它简单直接,但默认线程不安全,需要配合连接池使用,多线程环境下踩坑概率更高。如果你是刚起步,直接用Lettuce就好。

配置文件application.yml中基础项如下:

spring: data: redis: host: localhost port: 6379 password: 你的密码 database: 0 timeout: 3000ms lettuce: pool: max-active: 8 max-idle: 8 min-idle: 0

有几点要解释清楚。第一,spring.redis和spring.data.redis的区别在于版本——Spring Boot 2.x用spring.redis,Spring Boot 3.x改成了spring.data.redis。如果你升级了Boot大版本却发现配置不生效,大概率是这个问题。第二,连接池参数不是越大越好,max-active设成8在绝大多数场景够用,设太大反而会浪费连接资源,增加Redis服务端压力。第三,database默认0号库,如果项目里多业务共用一个Redis实例,建议按库隔离(0、1、2号库分开),但生产环境更推荐用不同的key前缀来隔离,因为SELECT切库在集群模式下是不支持的。

3.2 序列化器选择:乱码问题的根源和解决办法

如果你直接往Redis里塞一个User对象,再用客户端一看,发现存的是\xAC\xED\x00\x05t...这种乱码,那说明你踩到了序列化器配置的坑。原因很简单:Spring Boot默认的RedisTemplate用的是JdkSerializationRedisSerializer,它可以把任意Java对象转成二进制字节,但存进Redis后人类不可读,而且跨语言兼容性极差——你用Java存的数据,其他系统根本没法解析。更麻烦的是,这种序列化方式会把类的全限定名一起存进去,一旦实体类包名或字段结构变化,反序列化直接报错。

解决思路是统一替换序列化器。实际项目里我常用StringRedisSerializer处理key,配合GenericJackson2JsonRedisSerializer处理value。这样key变成可读的字符串,value保存的是JSON文本,直观且跨语言友好。具体配置如下:

@Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); StringRedisSerializer keySerializer = new StringRedisSerializer(); GenericJackson2JsonRedisSerializer valueSerializer = new GenericJackson2JsonRedisSerializer(); template.setKeySerializer(keySerializer); template.setHashKeySerializer(keySerializer); template.setValueSerializer(valueSerializer); template.setHashValueSerializer(valueSerializer); template.afterPropertiesSet(); return template; } }

注意HashKeySerializer和HashValueSerializer很容易被忽略,如果用到Hash结构而没设置,就会出现“HashMap的key是乱码”的诡异问题。另外,使用GenericJackson2JsonRedisSerializer时会在JSON里额外写入@class信息,虽然方便反序列化,但也会增加一点存储开销。如果数据敏感度比较高、不希望JSON里带类全名,可以考虑用Jackson2JsonRedisSerializer配合手动指定ObjectMapper,不过写法繁琐一些,新手更推荐前者。

还有一个经常被拿来做对比的是StringRedisTemplate。它默认key和value都用String序列化,所以不存在乱码问题,但这也意味着value存入前必须手动JSON.toJSONString(...),取出后需要JSON.parseObject(...)解析。说白了,StringRedisTemplate更底层灵活,RedisTemplate配好JSON序列化后更省事。我建议缓存对象用自定义的RedisTemplate,缓存简单字符串(验证码、token)用StringRedisTemplate,两者并存往往是最顺手的方式。

3.3 Redis读取工具类封装:不只为了“少写两行代码”

项目里直接到处写redisTemplate.opsForValue().get(key)不是不行,但很快会发现问题——key前缀没人统一、空值判断到处重复、过期时间随机设置。我更建议在整合阶段就顺手封装一个RedisUtil,把公共逻辑收敛进去。这个类的大致结构是:

  • 通用方法:set(key, value)、get(key)、delete(key)、expire(key, timeout),底层调用redisTemplate完成。
  • 带前缀方法:常量CACHE_KEY_PREFIX,如"project:user:",每次操作key时自动拼接业务前缀。
  • 防穿透方法:查询缓存为空时,区分“数据不存在”和“缓存未命中”,后者可以短暂缓存空值来防止下次查询继续打DB。
  • 分布式锁方法:基于SETNX实现tryLock(key, timeout)和unlock(key),简单场景够用。

具体实现代码网上很多模板,这里不展开,但封装时有一个原则值得记住:不要在工具类里塞入过多业务逻辑,它只处理通用的Redis数据结构操作,业务层自己决定怎么串起来。这样工具类稳定、易测试、可复用。

4. 核心应用场景实操:从缓存到分布式锁

4.1 缓存实战:从手动代码到Spring Cache注解

最直接的缓存用法是手动操作。比如查询用户信息前先看Redis有没有,有就直接返回,没有就查数据库再塞回Redis,还顺手加一个随机过期时间。代码大概是:

public UserVO getUserById(Long userId) { String key = "user:" + userId; Object cache = redisUtil.get(key); if (cache != null) { return JSON.parseObject(cache.toString(), UserVO.class); } UserVO user = userMapper.selectById(userId); if (user != null) { // 过期时间加随机值,避免同一时间大量缓存同时失效 redisUtil.set(key, JSON.toJSONString(user), 300 + new Random().nextInt(60)); } return user; }

这套逻辑足够清晰,但问题在于每次写缓存都要重复造轮子。更优雅的方式是使用Spring Cache,在启动类加上@EnableCaching,在方法上打@Cacheable、@CacheEvict、@CachePut注解,由框架自动管理缓存读写。比如:

@Cacheable(cacheNames = "user", key = "#userId") public UserVO getUserById(Long userId) { return userMapper.selectById(userId); } @CacheEvict(cacheNames = "user", key = "#userId") public void updateUser(Long userId) { // 修改数据库后删除缓存,下次访问重新加载 }

这里有一个很多新手会忽略的点:cacheNames对应Redis key的前缀部分,key是SpEL表达式,最终Redis里的key是user::1这种带双冒号的字符串。命名规范建议统一:业务模块 + 冒号分隔 + 业务ID。用Spring Cache虽然省事,但别忽略序列化器配置,默认的JDK序列化依然会导致不可读问题。

缓存场景里还常遇到缓存一致性课题,常见思路是“先更新数据库,再删除缓存”。为什么不是先删缓存再更新数据库呢?因为如果先删缓存,紧接着有并发读请求,就会把旧数据重新加载进缓存,而数据库此时还没更新完,缓存里就长期挂着脏数据。先更新DB再删缓存也有窗口期,但概率低得多。更严格的场景可以上用“延迟双删”策略:更新完数据库后删除一次缓存,过几百毫秒再删一次,把读请求可能写回的旧数据清掉。

4.2 分布式锁:从SETNX到Redisson,别在简单锁上栽跟头

单机部署时用Java的synchronized或JUC锁就能解决线程安全问题。一旦服务多实例部署,JVM锁就失效了,这就要用分布式锁。Redis实现分布式锁最常见的命令是SETNX,但不要直接setnx key value然后expire单独设过期时间,因为这两条命令不是原子的,进程在两步之间挂了,锁永远不释放。正确姿势是用一条命令把锁和过期时间绑在一起:

// 先尝试加锁,同时设置过期时间,防止死锁 Boolean success = stringRedisTemplate.opsForValue().setIfAbsent( lockKey, clientId, Duration.ofSeconds(30));

释放锁时也容易踩坑。如果你只执行delete(lockKey),有可能删掉的是别人后来抢到的锁。正确做法是:加锁时value存一个唯一标识(比如UUID或当前线程ID),释放前先用Lua脚本比较value是否一致,一致才删除。Spring Data Redis提供了DefaultRedisScript,支持把“比较+删除”写成Lua脚本原子执行,强烈建议这么做。

再进一步,生产上直接用Redisson框架更省心。它提供了RLock,使用上与JUC的ReentrantLock高度相似,并且内建了“看门狗”机制:如果锁的持有者没执行完,看门狗会自动续期,避免业务执行时间超过锁的过期时间导致提前释放。用法如下:

@Autowired private RedissonClient redissonClient; public void deductStock() { RLock lock = redissonClient.getLock("stock:lock"); lock.lock(30, TimeUnit.SECONDS); try { // 扣减库存的核心业务逻辑 } finally { if (lock.isHeldByCurrentThread()) { lock.unlock(); } } }

这里提醒一点:lock.lock()是阻塞等待,设置leaseTime之后即使正确释放前崩溃也不会死锁。具体用哪把锁,要看业务容忍度。简单场景SETNX足够,高并发秒杀和库存扣减建议Redisson。

4.3 高频业务场景:计数器、排行榜与Session共享

  • 计数与限流:INCR和EXPIRE配合,可以轻松实现接口访问次数统计、登录失败锁定、短信发送频率限制。比如限流一分钟最多10次,用INCR后如果值为1,设置过期时间60秒,之后判断计数是否超过阈值即可。
  • 排行榜:ZSet(有序集合)几乎是天然为排行榜设计的。ZADD添加玩家的积分,ZREVRANGE直接取前N名,ZINCRBY更新分数,性能极佳,比在MySQL里做ORDER BY score LIMIT N快得多。
  • Session共享:引入spring-session-data-redis这个依赖,并把server.servlet.session.store-type设为redis,Tomcat的Session就自动存到Redis里了。多实例部署后,用户在A实例登录,请求到B实例也不会掉线,这是业务集群化后很常见的需求。

5. 缓存治理与性能调优:真正拉开差距的地方

5.1 缓存穿透、击穿、雪崩:三大经典问题

这三个词在Redis面试题里出现频率极高,实际项目中更是真实存在,必须提前治理。

缓存穿透指查询一个不存在的key,Redis里没有,MySQL里也没有,请求直接打到数据库,恶意攻击会拖垮DB。解决思路有三种:一是对参数做基础校验,不合法直接拦截;二是缓存空值,比如null也写入Redis,过期时间短一些(3~5分钟);三是用布隆过滤器,把可能存在的数据标记进过滤器,查不到就快速返回。实际项目里最常见的是第二种,简单有效。

缓存击穿指一个热点key过期的一瞬间,大量请求同时打向数据库。解决思路可以用互斥锁:当发现缓存没命中时,先尝试获取分布式锁,拿到锁的线程去查数据库并回写缓存,其他线程短暂等待后重新读缓存。也可以用逻辑过期方案:缓存value里额外存一个过期时间戳,每次读取时判断是否逻辑过期,过期则异步去更新数据,但实现略复杂,一般并发量没到那个量级时不急着上。

缓存雪崩指大量key在同一时间段集体失效,或Redis服务整体挂了,导致请求全部打到数据库。解决思路很朴素:key的过期时间加一个随机偏移量(比如300秒加0~60秒随机数),避免同一秒过期;再给每个key设置合理的过期时间,别全部设置成同一个值。至于Redis服务高可用,那就靠主从+哨兵机制了,文章里不展开。

5.2 Big Key与热点Key识别与处理

存储一个几百KB甚至几MB的value,就是典型的Big Key。它会带来什么影响?大key在读取时占用网络带宽,在删除时可能阻塞Redis单线程,在迁移时也会拖慢整个集群。识别方式最简单的是用redis-cli --bigkeys扫描Redis内所有key,客户端工具里也有内存分析功能,可以直接看到占内存最大的key排名。

发现Big Key之后,处理思路一般是拆。一个几MB的JSON字符串,拆成多个hash field,或者压缩后再存储;一个存储了大量用户ID的List或Set,切成多个小key分片存储。热点Key的治理思路正好相反,它是某个key的访问量极高,单台Redis扛不住。常见做法是:做本地缓存(Caffeine)挡一部分读请求,或者把热点key复制N份加上随机后缀分散到不同分片。

这里补一句,关于Spring Boot集成Caffeine,实际上可以在Redis之上再加一层本地缓存,形成两级缓存架构。热点数据读本地的Caffeine,内存查不到再走Redis,Redis没有最后到MySQL。本地缓存命中率极高,能显著降低Redis压力。缺点是多了一层数据一致性维护成本,适合并发量极高、数据时效性要求又不算苛刻的团队。

5.3 内存策略、慢日志与日志切面

Redis不是无限内存的,生产环境必须配置淘汰策略。maxmemory-policy常见选择有allkeys-lru(所有key按LRU淘汰)和volatile-lru(仅对设置了过期时间的key按LRU淘汰)。如果业务里大部分数据都设置了过期时间,volatile-lru更安全,那些永久key不会被误删。

慢日志也是一个容易被忽视的监控点。在redis.conf中设置slowlog-log-slower-than 10000(单位微秒,超过10毫秒才记录),slowlog-max-len 128,就能通过SLOWLOG GET查看慢命令。大多数慢命令都是因为KEYS命令遍历所有key导致,这也是为什么我前面强调生产环境绝不能用KEYS *,要用SCAN代替。

调优层面,还有一个不容易注意到的点是连接池与线程池配合。Lettuce线程安全,理论上可以只用一个共享连接,但高并发下还是推荐启用连接池。连接数配置要结合Redis的tcp-keepalive和业务压力做调整,如果频繁出现连接超时,可以适当调大max-active,同时观察Redis端INFO clients命令确认已用连接数。

排查问题之前,最好把Redis的访问日志也接进来。除了Redis自身loglevel notice级别的运行日志,我建议在应用层做一层操作切面,统一记录缓存操作的key、耗时、结果,这样线上出问题时立刻能定位是哪条缓存操作慢、哪个key访问频率异常。Spring AOP即可实现,也方便你在测试环境验证缓存策略。

6. 常见问题与排查技巧实录

6.1 连接不上Redis:从ping到防火墙一网打尽

Spring Boot项目启动时,如果报Unable to connect to Redis或Connection refused,很多人第一反应是代码配置错了,但其实八成是环境或网络层面的问题。按我排查的顺序走:

  1. 先确认Redis进程活着:在Redis所在机器上执行redis-cli ping,如果返回PONG,说明Redis本身没问题;如果命令都找不到,去看进程是不是没启动。
  2. 确认绑定地址:默认Redis只允许本机连接,也就是bind 127.0.0.1。如果应用和Redis不在同一台机器上,必须把bind改成0.0.0.0或具体内网IP,否则从外部连不上。
  3. 检查保护模式:Redis 3.2之后默认开启protected-mode yes,即使bind了0.0.0.0,没有配置密码且监听在公网地址时也会拒绝外部访问。解决方法是设置requirepass密码后重启,或者显式关闭保护模式(不推荐,除非内网环境且可信)。
  4. 看防火墙和安全组:本机telnet 127.0.0.1 6379如果通,换到应用服务器上再试不行,大概率是云服务器安全组规则没放行6379端口。
  5. 看Spring配置是否生效:尤其注意Spring Boot 2.x与3.x配置前缀差异(前面已提过),以及@ConfigurationProperties是否正常绑定。

6.2 数据乱码或类型不匹配:先查序列化器

如果你看到Redis里存的是\xAC\xED\x00\x05t,不用怀疑,就是JDK默认序列化的锅。解决办法前面已经给过,把key换成StringRedisSerializer,value换成GenericJackson2JsonRedisSerializer。但如果你是从老项目接手,线上已经有大量JDK序列化脏数据,那要先把Redis里的数据清掉,再换配置。清理时用redis-cli --scan --pattern 'user:*' | xargs redis-cli del按规则批量删,别直接FLUSHALL,那会把所有库都给清了,生产环境千万别这么干。

还有一种情况是“类型不匹配”报错,比如存的是String,取的时候用opsForHash操作。这时要检查业务代码里是否对同一个key混用了不同类型操作。这种问题不好排查,因为报错不会第一时间指向具体位置。建议在封装的RedisUtil里强制规范类型操作,并让key带上前缀,从源头减少冲突。

6.3 缓存与数据库一致性问题:先定标准,再出方案

缓存和数据库的数据不一致,严格来说没有完美的实时解决方案,因为任何删除缓存的操作都有窗口期。比较务实的做法是:明确哪些数据要求秒级一致,哪些数据允许分钟级最终一致。前者直接用“先更新DB再删缓存”,必要时加延迟双删;后者设置相对短的过期时间,比如5分钟,过期后自然触发重新加载,脏数据最多存5分钟。

如果你在面试中或者项目中需要量化方案时,可以遵循一条硬规则:以数据库为准,缓存只是加速层。任何业务流程中,先写数据库,再删缓存;缓存重建时,只允许通过数据库查询结果回填,不允许客户端直接写缓存。这条规则配合过期时间兜底,能覆盖绝大多数场景。实在不行,引入消息队列做异步的缓存更新,但这已经是更重的架构设计,项目规模到那一步再说也不迟。

7. 关于版本与生态的扩展思考

Spring Boot版本的迭代节奏很快,目前新项目已经普遍用上Spring Boot 3.x,Java 17甚至Java 21都可以跑得很稳。如果你用的是Java 21 + Spring Boot 3.5,想要启用虚拟线程,Redis客户端也完全兼容,Lettuce本身支持异步非阻塞,配合虚拟线程的实际收益可能不像纯IO密集任务那么夸张,但配置成本很低。Spring Boot 3.x中启用虚拟线程大致只需设置spring.threads.virtual.enabled=true,值得一试。

另一个真实存在的扩展点是Spring Security配置迁移问题。Spring Boot 2.x中基于WebSecurityConfigurerAdapter的写法在3.x中已经废弃,如果项目同时用Redis做token存储或会话管理,升级时要同时处理两个兼容性变化。推荐的做法是尽早把安全配置迁移到基于SecurityFilterChain的写法上,这样和Redis的新版spring-data-redis客户端配合也更顺畅。旧代码里还有大量基于spring.redis.*的写法,升级后同样需要同步改为spring.data.redis.*,否则直接启动报错。

说到业务场景,我看到热词里有“基于Spring Boot的校园讲座预约系统”和“商城类设计题目”,这类项目在毕设和课程设计中很常见。它们使用Redis的场景通常是:讲座或商品的剩余名额做缓存和防超卖,预约码和下单验证码存在Redis并设置过期时间,热点讲座列表做缓存。如果你的项目也属于这一类,前面提到的缓存穿透、分布式锁基本都是核心得分点,文章里的代码和思路可以直接套用。

我个人的实际建议是,先从最基础的单机Redis + RedisTemplate开始,把缓存读写、过期时间、序列化搞明白,然后逐步接触Spring Cache、Redisson、集群部署。这些东西一个个理解透,面试和实战都会轻松不少。最后再分享一个小技巧:所有缓存key的前缀,命名格式统一为“项目名:业务名:ID”,比如mall:product:10001。这个习惯配合Redis Desktop Manager的按前缀搜索功能,排查效率能翻一倍。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询