Typography

一只奶牛猫

Redisson分布式锁的看门狗机制探究

发布于 # java

以下是优化后的文章格式,主要是改善了排版、标题层级和代码块的清晰度,方便阅读:

问题背景

在一个使用Spring AOP实现防重复提交功能的项目中,我们发现了一个有趣的现象:通过 @KaiNoRepeatSubmit 注解设置的锁过期时间(10秒)并没有生效,而是始终保持30秒才过期。这引发了我们对Redisson分布式锁实现机制的深入探究。

问题分析过程

1. 初始实现

最初的实现使用了Spring AOP的环绕通知和后置通知:

@Around(value = "noRepeatSubmitPoint(kaiNoRepeatSubmit)")
public Object judgeRepeatSubmit(ProceedingJoinPoint joinPoint, KaiNoRepeatSubmit kaiNoRepeatSubmit) throws Throwable {
    String key = getRequestKey(joinPoint, kaiNoRepeatSubmit);
    long seconds = kaiNoRepeatSubmit.seconds(); // 设置为10秒
    if (!kaiRedissonLockComponent.getLock(key, seconds, TimeUnit.SECONDS)) {
        return new DWServiceResult(false, "重复请求");
    }
    return joinPoint.proceed();
}

@After(value = "noRepeatSubmitPoint(kaiNoRepeatSubmit)")
public void afterMethod(JoinPoint joinPoint, KaiNoRepeatSubmit kaiNoRepeatSubmit) {
    kaiRedissonLockComponent.removeLock(getRequestKey(joinPoint, kaiNoRepeatSubmit));
}

2. 问题发现

通过日志观察,我们发现:

3. 深入分析

进一步研究发现这与Redisson的看门狗(WatchDog)机制有关:

Redisson默认配置

实际执行流程

解决方案

1. 配置修改

在Redisson配置中禁用看门狗机制:

@Bean
public RedissonClient redissonClient() {
    Config config = new Config();
    // ... 其他配置 ...
    config.setLockWatchdogTimeout(0L); // 禁用看门狗
    return Redisson.create(config);
}

2. 锁实现优化

修改锁的获取方式,避免看门狗干扰:

public boolean getLock(String lockName, long expireTime, TimeUnit timeUnit) {
    try {
        RLock lock = redissonClient.getLock(lockName + LOCK_FLAG);
        return lock.tryLock(0, expireTime, timeUnit);
    } catch (Exception e) {
        LOGGER.warn("获取锁失败", e);
        return false;
    }
}

3. 移除手动释放

删除 @After 注解方法,让锁自然过期:

@Around(value = "noRepeatSubmitPoint(kaiNoRepeatSubmit)")
public Object judgeRepeatSubmit(ProceedingJoinPoint joinPoint, KaiNoRepeatSubmit kaiNoRepeatSubmit) throws Throwable {
    String key = getRequestKey(joinPoint, kaiNoRepeatSubmit);
    if (!kaiRedissonLockComponent.getLock(key, kaiNoRepeatSubmit.seconds(), TimeUnit.SECONDS)) {
        return new DWServiceResult(false, "重复请求");
    }
    return joinPoint.proceed();
}

经验总结

  1. Redisson的看门狗机制是一把双刃剑
  1. 正确使用分布式锁需要
  1. 实践建议

参考资料


这个优化版更注重清晰的结构、代码的突出显示以及段落的分隔,以提升文章的可读性和逻辑性。