跳到内容

Redis Starter

受众:开发者 摘要:Spring Data Redis + Redisson 集成。RedisManager / RedissonManager / Topic / 分布式锁 / JSON 序列化 / 多实例 Pub/Sub 底座。

何时使用

场景建议
普通业务缓存cache.md Facade,直接用 RedisManager
Redis 数据结构(Hash / List / ZSet / Set)RedisManager
简单分布式锁(随机 token + Lua 释放)redisManager.tryLock(...)
看门狗续期锁、Topic、RAtomicLong 等RedissonManager
配置多实例广播spring.open.config.refresh.provider=redis
WebSocket 多实例spring.open.websocket.cluster.enabled=true
Sa-Token 跨实例登录态共享spring.open.auth.persistence.store=redis
单进程隔离诊断(无 Redis)关掉 starter 或全切 memory provider;普通开发不推荐绕开 Redis

Redis 是缓存和协调工具,不是长期事实数据源。重要业务数据必须落数据库。

机制说明

Data Redis starter 复用 Spring Boot 标准 spring.data.redis.* 连接信息,并在框架侧提供两层统一入口:

入口适用范围机制边界
RedisManagerString / Hash / List / Set / ZSet、TTL、计数、轻量锁统一 key 前缀和 JSON 序列化;轻量锁使用随机 token + Lua 校验释放;不负责业务缓存策略和长期数据一致性
RedissonManager看门狗锁、Topic、限流器、Redisson 高级对象所有业务 key 仍经过 RedisKeyResolver;需要高级协调能力时使用,普通业务缓存不要直接依赖
RedissonClientFacade 暂未覆盖的 Redisson 原生能力仅限高级场景,业务模块应优先尝试 RedisManager / RedissonManager

key 解析由 RedisKeyResolver 集中处理。业务代码只传 auth:token:1job:daily 这类业务 key,starter 会补齐应用级命名空间;如果 key 已经带当前前缀,则保持幂等返回。

Redisson 配置由 RedissonConfigFactory 生成,不使用 Redisson Spring Boot starter。mode=auto 时按 cluster -> sentinel -> single 顺序推断连接模式;用户名、密码、库编号和 SSL 默认沿用 Spring Boot Redis 配置,避免维护两套连接凭据。

快速开始

yaml
spring:
  data:
    redis:
      host: 127.0.0.1
      port: 6379
      password:
      database: 0
  open:
    data:
      redis:
        enabled: true

注入:

java
@RequiredArgsConstructor
@Service
public class SampleCacheService {
    private final RedisManager redisManager;
    private final RedissonManager redissonManager;
}

环境变量:

dotenv
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DATABASE=0

Cluster / Sentinel 用 Spring Boot 标准 spring.data.redis.cluster.* / spring.data.redis.sentinel.*。Redisson 默认复用同一连接信息。

Facade API

RedisManager(基础操作)

String

java
redisManager.set("sample:value", Map.of("name", "Alice"), Duration.ofMinutes(10));
Object value = redisManager.get("sample:value");
SampleValueVO vo = redisManager.get("sample:value", SampleValueVO.class);

Hash / List / Set / ZSet

java
redisManager.hSet("sample:hash", "name", "Alice");
String name = redisManager.hGet("sample:hash", "name", String.class);

redisManager.lRightPush("sample:list", "a");
Object popped = redisManager.lLeftPop("sample:list");

redisManager.sAdd("sample:set", "a", "b");
boolean exists = redisManager.sIsMember("sample:set", "a");

redisManager.zAdd("sample:zset", "task-1", System.currentTimeMillis());
Set<Object> tasks = redisManager.zRange("sample:zset", 0, 10);

TTL / 计数

java
redisManager.expire("sample:value", Duration.ofMinutes(5));
Duration ttl = redisManager.ttl("sample:value");

Long count = redisManager.increment("sample:counter");
redisManager.decrement("sample:counter", 2);

轻量锁(随机 token + Lua 释放,避免误删别人的锁):

java
Optional<RedisLock> lock = redisManager.tryLock("lock:order:1", Duration.ofSeconds(30));
if (lock.isEmpty()) return;
try {
    // 业务逻辑
} finally {
    redisManager.unlock(lock.get());
}

RedissonManager(高级协调)

看门狗续期锁

java
boolean executed = redissonManager.tryWithLock(
        "lock:job:daily-report",
        Duration.ofSeconds(1),
        Duration.ofMinutes(5),
        () -> {
            // 只允许一个实例执行
        });

Optional<String> value = redissonManager.tryWithLock(
        "lock:build:summary",
        Duration.ofSeconds(1),
        Duration.ofSeconds(30),
        () -> "ok");

Topic

java
RTopic topic = redissonManager.topic("config:changed");
topic.publish("refresh");

原生客户端(仅当抽象未覆盖时使用):

java
RedissonClient client = redissonManager.client();

配置项

yaml
spring:
  open:
    data:
      redis:
        enabled: true
        key-prefix: ""                  # 空时回退 spring:open:${spring.application.name}
        default-lock-ttl: 30s
        redisson:
          enabled: true
          mode: auto                    # auto / single / cluster / sentinel
          address: ""
          timeout: 3s
          connect-timeout: 10s
          retry-attempts: 3
          retry-interval: 1500ms
          lock-watchdog-timeout: 30s
          lazy-initialization: true
          threads: 0
          netty-threads: 0
配置默认值说明
enabledtrue启用 Data Redis starter
key-prefix应用级 key 前缀
default-lock-ttl30sRedisManager 基础锁默认 TTL
redisson.enabledtrue启用 Redisson
redisson.modeauto连接模式
redisson.lock-watchdog-timeout30s看门狗超时

mode=auto 推断规则:

模式触发条件
single默认
cluster配了 spring.data.redis.cluster.nodes
sentinel配了 spring.data.redis.sentinel.master

项目用 Redisson Spring Boot starter,直接接入 Redisson core,避开 Spring Boot 4 自动配置生命周期强绑定。

Key 前缀

默认:

text
spring:open:${spring.application.name}

业务 key cache:user:1 → 实际 Redis key spring:open:spring-open-application:cache:user:1

覆盖:

yaml
spring:
  open:
    data:
      redis:
        key-prefix: sample

业务代码自己拼应用级前缀,交给 RedisKeyResolverRedisManager

序列化

appRedisTemplate

部分序列化器
key / hash keyStringRedisSerializer.UTF_8
value / hash valueGenericJacksonJsonRedisSerializer

当前用 Spring Data Redis 4 + Jackson 3。对象结构变化时跨版本长期数据依赖 Redis value 作唯一来源。

Sa-Token 持久化复用 Spring Data Redis,但使用 auth 模块自己的 key 前缀。

Provider

Data Redis 本身提供 Provider 切换。扩展能力:

  • 自定义 RedisSerializer Bean 覆盖默认 JSON 序列化
  • 自定义 RedisKeyResolver Bean 改 key 前缀策略
  • 通过 RedissonConfigCustomizer 调整 Redisson 高级参数

上层模块复用

能力Redis 用途
Cacheredis store,默认共享缓存
Authspring.open.auth.persistence.store=redis 跨实例登录态
Config远程缓存 + Pub/Sub 多实例刷新
Queueredis provider 基于 List
Schedulerredis provider 基于 ZSet + Hash + 执行锁
WebSocket多实例广播基于 Redisson Topic

上层模块依赖各自 Facade,直接操作底层 Redis key。

Config 多实例刷新

yaml
spring:
  open:
    config:
      refresh:
        provider: redis
        redis-channel: config:changed

Pub/Sub 不是可靠队列:实例短暂离线可能错过广播。关键配置以数据库 + 缓存 TTL 兜底。

WebSocket 多实例

yaml
spring:
  open:
    websocket:
      cluster:
        enabled: true
        topic: websocket:commands

Topic 自动叠加 key 前缀,跨实例发送、广播和关闭连接走 Topic。

隔离诊断(无 Redis)

yaml
spring:
  open:
    cache:
      default-provider: memory
    auth:
      persistence:
        store: memory
    queue:
      provider: memory
    scheduler:
      provider: memory

或关 starter:

yaml
spring:
  open:
    data:
      redis:
        enabled: false

完整模式仍建议保留 Redis:缓存、登录态、多实例刷新和轻量协调能力开箱可用。

开发约定

  • 普通业务缓存用 Cache Facade,散落 RedisTemplate
  • Redis 数据结构 / 锁 / Topic / 底层协调用 RedisManager / RedissonManager
  • key 命名冒号分层:cache:user:1 / lock:order:1 / queue:default
  • key 含明文手机号、邮箱、token、私钥
  • 锁必须设 TTL,并在 finally 中释放
  • Pub/Sub 只做通知,承载必须送达的数据
  • 多实例状态以数据库保证最终一致,Redis 负责加速和协调

验证命令

bash
./mvnw -pl spring-open-starters/spring-open-starter-data-redis -am test -DskipITs
./mvnw -pl spring-open-application -am test -DskipITs -DskipFrontend

相关

Released under the Apache License 2.0.