游乐游手机版
首页/AI教程/文章详情

SpringBoot分布式缓存实战指南

时间:2026-08-04 14:14
分布式缓存解决单机缓存不共享、更新不同步问题,结合本地缓存与Redis缓存,利用Redis发布订阅机制实现节点间缓存同步。tools-redis工具基于此思路,支持Caffeine与Redis两级缓存,提供配置灵活、注解式使用方式。

如果你对 SpringBoot 缓存机制尚不熟悉,建议先阅读之前介绍 SpringBoot 集成 Caffeine 实现本地缓存的相关文章。今天我们来探讨一个重要问题:为什么需要引入分布式缓存?

在实际项目开发中,单机应用往往难以承受业务压力,随着系统规模增长,通常需要采用分布式部署。然而,分布式架构会带来一个典型问题:每个服务实例都拥有独立的本地缓存,彼此之间无法共享数据。更棘手的是,当某个服务更新了缓存后,其他服务无法感知到这一变化,用户请求若落到其他节点,读取到的仍是旧数据,导致缓存不一致。此时,许多开发者会想到借助 Redis 来解决,但 Redis 作为独立的第三方中间件,存在网络延迟开销,且所有缓存请求都集中到 Redis 上,在高并发场景下 Redis 可能成为性能瓶颈,甚至直接宕机。因此,一个更可靠的设计思路是:将本地缓存(如 Caffeine)与 Redis 分布式缓存相结合,并利用 Redis 的发布订阅(Pub/Sub)机制,当某个服务更新缓存时,主动通知其他服务同步更新,从而保证缓存一致性。

接下来,我将介绍一个基于上述思路开源的轻量级分布式缓存工具——tools-redis,它正是围绕这一设计实现的。

一、引入 Maven 依赖


    cn.gjing
    tools-redis
    1.2.0

二、在启动类上添加缓存注解

/**
 * @author Gjing
 */
@SpringBootApplication
@EnableToolsCache
public class TestRedisApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestRedisApplication.class, args);
    }
}

三、配置参数说明

1. 配置项一览

所有配置项均以 tools.cache 为前缀,支持按需自定义。以下是完整的配置项列表:

配置项描述
cache-names缓存 key 的名称
cache-value-nullable是否允许缓存空值,默认 true,防止缓存穿透
dynamic是否动态根据 cacheName 创建 Cache 实现,默认 true
cache-prefix缓存 key 的前缀
caffeine.initial-capacityCaffeine 初始化大小
caffeine.expire-after-access访问后过期时间,单位毫秒
caffeine.expire-after-write写入后过期时间,单位毫秒
caffeine.maximum-size最大缓存对象个数,超过此数量时之前放入的缓存会失效
caffeine.refresh-after-write写入后刷新时间,单位毫秒
redis.every-cache-expire每个 cacheName 的过期时间,单位秒,优先级比 expire 高
redis.expire全局过期时间,单位秒,默认不过期
redis.topic缓存更新时通知其他节点的 topic 名称

2. 配置示例

YAML 配置方式

tools:
  cache:
    cache-prefix: 锁的前缀
    redis:
      expire: 10
    caffeine:
      expire-after-write: 3000

JavaBean 配置方式

/**
 * @author Gjing
 */
@Configuration
public class CacheConfiguration {

    @Bean
    public ToolsCache toolsCache() {
        return ToolsCache.builder()
                .cachePrefix("锁的前缀")
                .dynamic(true)
                .build();
    }

    @Bean
    public RedisCache redisCache() {
        return RedisCache.builder()
                .expire(10)
                .build();
    }

    @Bean
    public CaffeineCache caffeineCache() {
        return CaffeineCache.builder()
                .expireAfterWrite(3000)
                .build();
    }
}

三、快速使用示例

/**
 * @author Gjing
 */
@Service
@Slf4j
public class CustomService {

    @Resource
    private CustomRepository customRepository;

    /**
     * 获取一个用户
     * @param customId 用户id
     * @return Custom
     */
    @Cacheable(value = "user", key = "#customId")
    public Custom getCustom(Integer customId) {
        log.warn("查询数据库用户信息");
        return customRepository.findById(customId)
                .orElseThrow(() -> new NullPointerException("User is not exist"));
    }

    /**
     * 删除一个用户
     * @param customId 用户id
     */
    @CacheEvict(value = "user", key = "#customId")
    public void deleteUser(Integer customId) {
        Custom custom = customRepository.findById(customId)
                .orElseThrow(() -> new NullPointerException("User is not exist"));
        customRepository.delete(custom);
    }
}

四、定义 REST 接口调用

/**
 * @author Gjing
 */
@RestController
public class CustomController {

    @Resource
    private CustomService customService;

    @GetMapping("/user/{custom-id}")
    @ApiOperation(value = "查询用户", httpMethod = "GET")
    public ResponseEntity getUser(@PathVariable("custom-id") Integer customId) {
        return ResponseEntity.ok(customService.getCustom(customId));
    }

    @DeleteMapping("/user")
    @ApiOperation(value = "删除用户", httpMethod = "DELETE")
    @ApiImplicitParam(name = "customId", value = "用户Id", dataType = "int", required = true, paramType = "Query")
    @NotNull
    public ResponseEntity deleteUser(Integer customId) {
        customService.deleteUser(customId);
        return ResponseEntity.ok("Successfully delete");
    }
}

实际调用结果如下所示:

res

如果在使用过程中遇到任何问题,欢迎留言交流,我会及时回复并持续更新项目。项目源码地址:tools-redis。

来源:https://developer.aliyun.com/article/706643
上一篇SpringBoot分布式锁实现与使用指南 下一篇华山版Java开发手册作者详解工程师如何避免代码陷阱
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
CAD零基础入门教程:坐标输入、图层管理与基础绘图命令
AI教程 · 2026-09-01

CAD零基础入门教程:坐标输入、图层管理与基础绘图命令

本文面向CAD零基础学习者,系统讲解坐标输入、图层管理与基础绘图命令的核心用法。通过分步实操与常见问题排查,帮助新手建立精确绘图习惯,掌握规范出图的基础能力。

CAD从入门到项目交付:绘图、标注、图块与实战工作流
AI教程 · 2026-09-01

CAD从入门到项目交付:绘图、标注、图块与实战工作流

掌握CAD的核心在于建立“画得准、标得清、复用快、交付稳”的工作流。本文提供从环境设置、高频命令组合、标注规范、图块标准化到项目分阶段交付的完整路径,帮助初学者避免常见返工陷阱,独立完成可检查、可复用、可打印的工程图纸。

Claude Code 登录指南:个人、Teams 与企业账号区分与授权步骤
AI教程 · 2026-09-01

Claude Code 登录指南:个人、Teams 与企业账号区分与授权步骤

本文详细解析 Claude Code 登录前的账号类型区分方法,涵盖个人订阅、Teams 席位与企业 Enterprise 席位的授权路径差异。提供终端登录命令、环境变量排查及常见异常处理步骤,帮助用户快速完成正确授权并避免登录路径混淆。

Claude Code 文件修改前的权限模式配置与命令审批指南
AI教程 · 2026-09-01

Claude Code 文件修改前的权限模式配置与命令审批指南

本文详细介绍Claude Code在修改文件前的权限模式配置方法,包括defaultMode可选值、permissions allow与deny规则设置、多层级配置文件管理以及 status验证技巧,帮助开发者安全高效地使用AI编程助手。

Claude Code接入VS Code后先测扩展和终端命令
AI教程 · 2026-09-01

Claude Code接入VS Code后先测扩展和终端命令

在VS Code中接入Claude Code后,建议优先验证扩展面板与集成终端两条入口。本文提供标准检查顺序、关键命令与常见故障排查路径,帮助你快速确认环境就绪,避免后续开发受阻。