分布式锁Redisson在SpringBoot中的应用
编辑
1197
2023-03-10
前言
分布式锁,在现下规模应用环境中,充当重要的角色,在集群/分布式环境中、在多线程互斥抢占共享资源的情景下,分布锁是主流直接有效的办法。
这里不讨论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包,达到引入该依赖无需任何额外配置即可使用此功能的效果?
设计
- 通过注解
@DistributedLock
标记拦截目标方法 - 在切面中读取方法参数,取注解
@DistributedKey
标记的参数值,作为锁的Key值,此值通常为共享资源的ID - 若取不到锁Key值,则抛出RuntimeException异常
- 若取到锁Key值,拿此Key去尝试申请锁
- 若获取锁失败,表示此资源已被占用,抛出DistributedLockException异常
- 若获取锁成功,则执行目标方法
- 若执行目标方法耗时大于锁的存活时长,锁到期时Redis将自动释放锁
- 若执行目标方法耗时小于锁的存活时长,由当前线程主动告知Redis释放锁
- 锁被释放后,其他线程可以申请成功
实现、用法
实现细节看代码,有分布式锁的功能实现,和SpringBoot应用自动装配实现,用起来就比较方便。
这里是代码仓库
附录
Redisson - https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95
- 0
- 0
-
分享