一個(gè)強(qiáng)大的分布式鎖框架——Lock4j
共 4604字,需瀏覽 10分鐘
·
2024-07-18 11:59
每日技術(shù)干貨,第一時(shí)間送達(dá)!
一、簡介
Lock4j是一個(gè)分布式鎖組件,它提供了多種不同的支持以滿足不同性能和環(huán)境的需求,基于Spring AOP的聲明式和編程式分布式鎖,支持RedisTemplate、Redisson、Zookeeper。
二、特性
? 簡單易用,功能強(qiáng)大,擴(kuò)展性強(qiáng)。
? 支持redission, redisTemplate, zookeeper,可混用,支持?jǐn)U展。
開源地址:
https://gitee.com/baomidou/lock4j
三、使用前準(zhǔn)備
3.1 引入依賴
<!-- Lock4j -->
<!-- 若使用redisTemplate作為分布式鎖底層,則需要引入 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>lock4j-redis-template-spring-boot-starter</artifactId>
<version>2.2.4</version>
</dependency>
<!-- 若使用redisson作為分布式鎖底層,則需要引入 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>lock4j-redisson-spring-boot-starter</artifactId>
<version>2.2.4</version>
</dependency>
3.2 添加redis配置
spring:
redis:
database:0
# Redis服務(wù)器地址 寫你的ip
host:127.0.0.1
# Redis服務(wù)器連接端口
port:6379
# Redis服務(wù)器連接密碼(默認(rèn)為空)
password:
# 連接池最大連接數(shù)(使用負(fù)值表示沒有限制 類似于mysql的連接池
jedis:
pool:
max-active:200
# 連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒有限制) 表示連接池的鏈接拿完了 現(xiàn)在去申請(qǐng)需要等待的時(shí)間
max-wait:-1
# 連接池中的最大空閑連接
max-idle:10
# 連接池中的最小空閑連接
min-idle:0
# 連接超時(shí)時(shí)間(毫秒) 去鏈接redis服務(wù)端
timeout: 6000
四、注解屬性介紹
package com.baomidou.lock.annotation;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public@interfaceLock4j{
Stringname()default"";
Class<?extendsLockExecutor> executor()defaultLockExecutor.class;
String[] keys()default{""};
longexpire()default-1L;
longacquireTimeout()default-1L;
booleanautoRelease()defaulttrue;
}
五、簡單使用
@RestController
@RequestMapping("/mock")
publicclassMockController{
@GetMapping("/lockMethod")
@Lock4j(keys = {"#key"}, acquireTimeout = 1000, expire = 10000)
publicResultlockMethod(@RequestParam String key){
ThreadUtil.sleep(5000);
returnResult.OK(key);
}
}
打開瀏覽器窗口,重復(fù)刷新訪問:
http://localhost:8080/mock/lockMethod?key=123
成功獲得鎖訪問結(jié)果:
{
"success":true,
"message":"操作成功!",
"code":200,
"result":"123",
"timestamp":1678866083211
}
搶占不到鎖,Lock4j會(huì)拋出
com.baomidou.lock.exception.LockFailureException: request failed,please retry it.
異常,通過全局異常處理返回如下結(jié)果:
{
"success":false,
"message":"操作失敗,request failed,please retry it.",
"code":500,
"result":null,
"timestamp":1678866034929
}
六、高級(jí)使用
6.1 自定義執(zhí)行器Exector
/**
* 自定義分布式鎖執(zhí)行器
*
* @author: austin
* @since: 2023/3/15 15:45
*/
@Component
publicclassCustomRedissonLockExecutorextendsAbstractLockExecutor{
@Override
publicObjectacquire(String lockKey, String lockValue, long expire, long acquireTimeout){
returnnull;
}
@Override
publicbooleanreleaseLock(String key, String value, Object lockInstance){
returnfalse;
}
}
在注解上直接指定特定的執(zhí)行器:
@Lock4j(executor = CustomRedissonLockExecutor.class)。
6.2 自定義分布式鎖key生成器
/**
* 自定義分布式鎖key生成器
*
* @author: austin
* @since: 2023/3/15 15:46
*/
@Component
publicclassCustomKeyBuilderextendsDefaultLockKeyBuilder{
publicCustomKeyBuilder(BeanFactory beanFactory){
super(beanFactory);
}
}
6.3 自定義搶占鎖失敗執(zhí)行策略
/**
* 自定義搶占鎖失敗執(zhí)行策略
*
* @author: austin
* @since: 2023/3/15 15:49
*/
@Component
publicclassGrabLockFailureStrategyimplementsLockFailureStrategy{
@Override
publicvoidonLockFailure(String key, Method method, Object[] arguments){
}
}
默認(rèn)的鎖獲取失敗策略為
com.baomidou.lock.DefaultLockFailureStrategy.
6.4 手動(dòng)加鎖釋放鎖
@Service
publicclassLockServiceImplimplementsLockService{
@Autowired
privateLockTemplate lockTemplate;
@Override
publicvoidlock(String resourceKey){
LockInfolock= lockTemplate.lock(resourceKey,10000L,2000L,CustomRedissonLockExecutor.class);
if(lock ==null){
// 獲取不到鎖
thrownewFrameworkException("業(yè)務(wù)處理中,請(qǐng)稍后再試...");
}
// 獲取鎖成功,處理業(yè)務(wù)
try{
doBusiness();
}catch(Exception e){
thrownewRuntimeException(e);
}finally{
lockTemplate.releaseLock(lock);
}
}
privatevoiddoBusiness(){
// TODO 業(yè)務(wù)執(zhí)行邏輯
}
}
江湖再見,明天見。
— 【 THE END 】—
公相逢即是緣,少俠可否點(diǎn)贊在看,在下不勝感激!
評(píng)論
圖片
表情
