lock 為 java 設計的分散式鎖,開箱即用,縱享絲滑。
開源地址:https://github.com/houbb/lock
開箱即用,支援註解式和過程式呼叫
基於 redis 的分散式鎖
內建支援多種 redis 的整合方式
漸進式設計,可獨立於 spring 使用
整合 spring
整合 spring-boot
jdk1.7+
maven 3.x+
<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()) //釋放鎖失敗處理
;
<dependency>
<groupId>com.github.houbb</groupId>
<artifactId>lock-spring</artifactId>
<version>1.3.0</version>
</dependency>
@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
的引導類,這種適合一些更加靈活的場景。
@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);
}
}
}
當然,我們可以在方法上直接指定註解 @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;
}
<dependency>
<groupId>com.github.houbb</groupId>
<artifactId>lock-springboot-starter</artifactId>
<version>1.3.0</version>
</dependency>
同 spring
持有鎖的執行緒可以多次獲取鎖
redis-config: 相容各種常見的 redis 設定模式