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 个令牌,适合短信验证码这类防刷场景。