Heycm

Heycm

分布式锁Redisson在SpringBoot中的应用

1197
2023-03-10
分布式锁Redisson在SpringBoot中的应用

前言

  分布式锁,在现下规模应用环境中,充当重要的角色,在集群/分布式环境中、在多线程互斥抢占共享资源的情景下,分布锁是主流直接有效的办法。
这里不讨论Redisson本身,他的原理他的加锁算法他的实现机制,如果想了解Redisson去读官网更加合适(附录),讨论的是Redisson的在SpringBoot中的应用。

缘起

  在SpringBoot应用中使用Redisson实现分布式锁已经是很方便了,如下:

RLock lock = redisson.getLock("anyLock");
// 尝试加锁,最多等待100秒,上锁以后10秒自动解锁
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {
   try {
     ...
   } finally {
       lock.unlock();
   }
}

但是,每一个需要获取锁的情景,都要写一版这个代码块,这个代码看起来就不简洁很啰嗦很难看。
所以,考虑将这个代码模板抽取封装,是不是可以通过一个简单的注解+AOP锁住一个方法,以省去这些重复繁杂的代码步骤?
再来,在SpringBoot中的应用,是不是可以将这个分布式锁注解功能打成一个开箱即用的starter包,达到引入该依赖无需任何额外配置即可使用此功能的效果?

设计

distributed-lock

  1. 通过注解@DistributedLock标记拦截目标方法
  2. 在切面中读取方法参数,取注解@DistributedKey标记的参数值,作为锁的Key值,此值通常为共享资源的ID
  3. 若取不到锁Key值,则抛出RuntimeException异常
  4. 若取到锁Key值,拿此Key去尝试申请锁
  5. 若获取锁失败,表示此资源已被占用,抛出DistributedLockException异常
  6. 若获取锁成功,则执行目标方法
  7. 若执行目标方法耗时大于锁的存活时长,锁到期时Redis将自动释放锁
  8. 若执行目标方法耗时小于锁的存活时长,由当前线程主动告知Redis释放锁
  9. 锁被释放后,其他线程可以申请成功

实现、用法

  实现细节看代码,有分布式锁的功能实现,和SpringBoot应用自动装配实现,用起来就比较方便。
这里是代码仓库

附录

Redisson - https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95

项目代码 - https://gitee.com/heycm/distributed-lock