1、简介
1.1、项目
1.2、介绍
- 支持redisson、zookeeper分布式锁
- redisson支持重入锁、读写锁、联锁、红锁、公平锁
- zookeeper支持重入锁、不可重入锁、读写锁、联锁
- 支持注解、方法调用、函数式编程等方式加锁
- 支持多注解,对同一方法加不同的锁
- 锁的key支持SpEL表达式
- 支持自定义全局、方法级加锁失败回调
- 方法级失败回调:方法名、参数类型列表相同,支持相同类型的返回
1.3 分布式锁注解KylinLock字段使用说明
- name:锁的key一部分,为空则会使用:包名.类名.方法名
- keys:锁的key一部分 支持 SpEL表达式,锁的key = prefix:name#keys
- expire:过期时间 单位:毫秒
- acquireTimeout:获取锁超时时间 单位:毫秒
- executor:锁执行器
- lockType:锁类型,默认重入锁
- keySuffix:联锁、红锁个数以及其中每个锁的后缀key,默认:{"1", "2", "3"},支持SpEL 表达式
- lockFailure:加锁失败回调类
2、使用说明
2.1、引入依赖
<dependency>
<groupId>com.gitee.wangjkui</groupId>
<artifactId>kylin-lock-spring-boot-starter</artifactId>
<version>Latest Version</version>
</dependency>
2.2、配置
2.2.1、application.yml
spring:
redis:
redisson:
file: classpath:redisson.yml
kylin:
lock:
acquire-timeout: 3000
expire: 30000
retry-interval: 100
lock-key-prefix: kylin-lock
primary-executor: com.wjk.kylin.lock.executor.redisson.RedissonLockExecutor
redisson: true
zookeeper:
zk-servers: 127.0.0.1:2181
session-timeout: 60000
connection-timeout: 15000
base-sleep-time-ms: 5000
max-retries: 3
namespace: curator/kylin/lock
2.2.2、redisson.yml
singleServerConfig:
idleConnectionTimeout: 10000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
password: redis123
subscriptionsPerConnection: 5
address: redis://127.0.0.1:6379
subscriptionConnectionMinimumIdleSize: 1
subscriptionConnectionPoolSize: 50
connectionMinimumIdleSize: 32
connectionPoolSize: 64
database: 2
dnsMonitoringInterval: 5000
codec: !<org.redisson.codec.JsonJacksonCodec> {}
transportMode: "NIO"
2.3、使用案例
2.3.1、重入锁
@KylinLock(name = "reentrant_key", expire = 60000)
public void demoMethod2() {
System.out.println("demoMethod2 - start" + getClass());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
indexService.demoMethod2();
System.out.println("demoMethod2 - end " + getClass());
}
2.3.2 、读写锁
@Override
@KylinLock(name = "read-write", acquireTimeout = 0, lockType = LockType.READ)
public void read1(String key) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行方法read1 , 当前线程:" + Thread.currentThread().getName() + "threadId:" + Thread.currentThread().getId());
}
2.3.3、联锁
@KylinLock(lockType = LockType.MULTI)
public void demoMethod6() {
System.out.println("demoMethod6 - start" + getClass());
try {
Thread.sleep(40000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("demoMethod6 - end " + getClass());
}
2.3.4、红锁
@KylinLock(lockType = LockType.RED, keySuffix = {"#user.id", "'red2'"}, executor = RedissonLockExecutor.class)
public void demoMethod11(User user) {
System.out.println("demoMethod11 - start" + getClass());
try {
Thread.sleep(40000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("demoMethod11 - id:" + user.getId() + ",name:" + user.getName());
}
2.3.5、公平锁
@KylinLock(name = "fair_lock_key", lockType = LockType.FAIR, executor = RedissonLockExecutor.class)
public void demoMethod8() {
System.out.println("demoMethod8 - start" + getClass());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
indexService.demoMethod8();
System.out.println("demoMethod8 - end " + getClass());
}
2.3.6、多注解
@KylinLock(name = "reentrant_key1", expire = 60000)
@KylinLock(name = "reentrant_key2", expire = 60000)
@KylinLock(name = "reentrant_key3", expire = 60000)
public void demoMethod3() {
System.out.println("demoMethod3 - start" + getClass());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("demoMethod3 - end " + getClass());
}
2.3.7、函数式编程
public void execute1(String key) {
Integer num = lockTemplate.execute(key, IndexServiceImpl::getNumber);
System.out.println("执行execute方法1 , 当前线程:" + Thread.currentThread().getName() + " , 获取的返回值是:" + num);
}
public static Integer getNumber() {
try {
Thread.sleep(40000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行getNumber方法 , 当前线程:" + Thread.currentThread().getName());
return 1;
}
2.3.8、自定义加锁失败执行方法
@KylinLock(acquireTimeout = 0, lockFailure = DemoLockFailureCallBack.class)
public Integer demoMethod14(Integer num) {
System.out.println("demoMethod12 - start,num:" + num);
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("demoMethod12 - end,num:" + num);
return num * 2;
}
@Slf4j
@Component
public class DemoLockFailureCallBack implements LockFailureCallBack {
public Integer demoMethod14(Integer num) {
log.error("demoMethod14-方法自定义失败回调,入参num:{}", num);
return -1;
}
}