Skip to content

Redisson

Redisson 是 Redis 官方协议上的 Java 客户端。它不只是封装 Redis 命令,还提供了很多分布式对象和工具,例如分布式锁、信号量、限流器、阻塞队列、延迟队列等。

Redisson 能做什么

能力说明
RLock分布式可重入锁
RReadWriteLock分布式读写锁
RSemaphore分布式信号量
RRateLimiter分布式限流器
RBlockingQueue分布式阻塞队列
RDelayedQueue分布式延迟队列

加锁流程

mermaid
flowchart TD
    A[调用 lock] --> B[执行 Lua 脚本]
    B --> C{锁是否存在?}
    C -->|不存在| D[写入锁 key 和线程标识]
    C -->|当前线程持有| E[重入次数加 1]
    C -->|其他线程持有| F[订阅释放消息并等待]
    D --> G[启动看门狗续期]
    E --> G

为什么使用 Lua 脚本

Redis 单条命令是原子的,但加锁通常需要判断、写入、设置过期时间等多个步骤。Redisson 使用 Lua 脚本把多个步骤放在 Redis 服务端一次执行,保证原子性。

看门狗机制

如果调用 lock() 时没有指定过期时间,Redisson 会启动看门狗自动续期。只要业务线程还活着,锁就会定期续期,避免业务没执行完锁却过期。

如果指定了明确的 leaseTime,看门狗不会自动续期,到期后锁会自动释放。

目录

使用建议

  1. 优先给锁设置合理的等待时间,避免线程无限等待。
  2. 临界区代码要尽量短,不要在锁内执行慢接口。
  3. 解锁必须放在 finally 中。
  4. 释放锁前要确认当前线程持有锁。
  5. 对强一致要求极高的场景,要评估 Redis 锁是否足够。

常见风险和排查

风险产生原因排查和处理
锁等待时间过长业务在锁内执行慢接口或大事务缩短临界区,设置 tryLock 等待时间
锁提前释放指定的 leaseTime 小于业务执行时间使用看门狗,或合理设置过期时间
解锁报错当前线程并不持有锁解锁前判断 isHeldByCurrentThread()
Redis 故障导致锁不可用锁状态依赖 Redis关键业务要设计降级、补偿或人工处理
把锁当事务用Redis 锁只能控制并发入口数据一致性仍要靠数据库事务和唯一约束

Redisson 能减少手写 Redis 锁的错误,但不能消除分布式系统的一致性风险。锁只保护临界区并发,不负责业务补偿、事务提交和外部接口幂等。

代码 Demo:Redisson 限流器

java
@Service
public class SmsRateLimitService {
    private final RedissonClient redissonClient;

    public boolean tryAcquire(String phone) {
        RRateLimiter limiter = redissonClient.getRateLimiter("sms:limit:" + phone);
        limiter.trySetRate(RateType.OVERALL, 1, 60, RateIntervalUnit.SECONDS);
        return limiter.tryAcquire();
    }
}

使用:

java
if (!smsRateLimitService.tryAcquire(phone)) {
    throw new BizException("发送太频繁,请稍后再试");
}

这个 Demo 表示同一个手机号 60 秒内只允许获取 1 个令牌,适合短信验证码这类防刷场景。