(java 實現開箱即用基於 redis 的分散式鎖
阿新 • • 發佈:2022-12-08
專案簡介
lock 為 java 設計的分散式鎖,開箱即用,縱享絲滑。
開源地址:https://github.com/houbb/lock
目的
-
開箱即用,支援註解式和過程式呼叫
-
基於 redis 的分散式鎖
-
內建支援多種 redis 的整合方式
-
漸進式設計,可獨立於 spring 使用
-
整合 spring
-
整合 spring-boot
快速開始
需要
jdk1.7+
maven 3.x+
maven 引入
<dependency> <groupId>com.github.houbb</groupId> <artifactId>lock-core</artifactId> <version>1.3.0</version> </dependency>
入門例子
基於本地 redis 的測試案例。
public void helloTest() { ILock lock = LockBs.newInstance(); String key = "ddd"; try { // 加鎖 lock.tryLock(key); System.out.println("業務處理"); } catch (Exception e) { throw new RuntimeException(e); } finally { // 釋放鎖 lock.unlock(key); } }
配置化
為了便於拓展,LockBs 的配置支援自定義:
LockBs.newInstance() .id(Ids.uuid32()) //id 生成策略 .cache(JedisRedisServiceFactory.pooled("127.0.0.1", 6379)) //快取策略 .lockSupport(new RedisLockSupport()) // 鎖實現策略 .lockKeyFormat(new LockKeyFormat()) // 針對 key 的格式化處理策略 .lockReleaseFailHandler(new LockReleaseFailHandler()) //釋放鎖失敗處理 ;
整合 spring
maven 引入
<dependency>
<groupId>com.github.houbb</groupId>
<artifactId>lock-spring</artifactId>
<version>1.3.0</version>
</dependency>
指定 bean 使用
啟用分散式鎖
@EnableLock
啟用分散式鎖。
@EnableRedisConfig
啟用 redis 的預設配置。
@Configurable
@ComponentScan(basePackages = "com.github.houbb.lock.test.service")
@EnableLock
@EnableRedisConfig
public class SpringConfig {
}
EnableLock
註解說明,和引導類對應:
public @interface EnableLock {
/**
* 唯一標識生成策略
* @return 結果
*/
String id() default "lockId";
/**
* 快取實現策略 bean 名稱
*
* 預設引入 redis-config 中的配置
*
* @return 實現
*/
String cache() default "springRedisService";
/**
* 加鎖 key 格式化策略
* @return 策略
*/
String lockKeyFormat() default "lockKeyFormat";
/**
* 鎖釋放失敗處理類
* @return 結果
*/
String lockReleaseFailHandler() default "lockReleaseFailHandler";
}
其中 springRedisService
使用的是 redis-config 中的實現。
對應註解 @EnableRedisConfig
,redis 的配置資訊如下:
配置 | 說明 | 預設值 |
---|---|---|
redis.address | redis 地址 | 127.0.0.1 |
redis.port | redis 埠 | 6379 |
redis.password | redis 密碼 |
使用 LockBs
我們可以直接 LockBs
的引導類,這種適合一些更加靈活的場景。
@ContextConfiguration(classes = SpringConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringServiceRawTest {
@Autowired
private UserService userService;
@Autowired
private LockBs lockBs;
@Test
public void queryLogTest() {
final String key = "name";
try {
lockBs.tryLock(key);
final String value = userService.rawUserName(1L);
} catch (Exception exception) {
throw new RuntimeException(exception);
} finally {
lockBs.unlock(key);
}
}
}
aop 註解使用
指定方法註解
當然,我們可以在方法上直接指定註解 @Lock
,使用更加方便。
直接使用,AOP 切面生效即可。
@Service
public class UserService {
@Lock
public String queryUserName(Long userId) {
}
@Lock(value = "#user.name")
public void queryUserName2(User user) {
}
}
@Lock
屬性說明,value 用於指定 key,支援 SPEL 表示式。
其他屬性,和引導類的方法引數一一對應。
public @interface Lock {
/**
* 快取的 key 策略,支援 SpEL
* @return 結果
*/
String value() default "";
/**
* 時間單位
* @return 單位
*/
TimeUnit timeUnit() default TimeUnit.SECONDS;
/**
* 等待鎖時間
* @return 等待鎖時間
*/
long waitLockTime() default 10;
/**
* 業務加鎖時間
* @return 加鎖時間
*/
long lockTime() default 60;
}
spring boot 整合
maven 引入
<dependency>
<groupId>com.github.houbb</groupId>
<artifactId>lock-springboot-starter</artifactId>
<version>1.3.0</version>
</dependency>
使用
同 spring
後期 Road-MAP
持有鎖的執行緒可以多次獲取鎖