基于redisson、zookeeper实现的分布式锁kylin-lock

1、简介

1.1、开源项目

1.2、介绍

  1. 支持redisson、zookeeper分布式锁
  2. redisson支持重入锁、读写锁、联锁、红锁、公平锁
  3. zookeeper支持重入锁、不可重入锁、读写锁、联锁
  4. 支持注解、方法调用、函数式编程等方式加锁
  5. 支持多注解,对同一方法加不同的锁
  6. 锁的key支持SpEL表达式
  7. 支持自定义全局、方法级加锁失败回调
  8. 方法级失败回调:方法名、参数类型列表相同,支持相同类型的返回

1.3 分布式锁注解KylinLock字段使用说明

2、使用说明

2.1、引入依赖


    com.gitee.wangjkui
    kylin-lock-spring-boot-starter
    Latest Version

2.2、配置

2.2.1、application.yml

spring:
  redis:
    redisson:
      file: classpath:redisson.yml

#分布式锁
kylin:
  lock:
    acquire-timeout: 3000       #获取锁超时时间 默认值3000L 单位:毫秒
    expire: 30000               #过期时间,默认值30000L 单位:毫秒
    retry-interval: 100         #获取锁失败时重试时间间隔,默认值100L 单位:毫秒
    lock-key-prefix: kylin-lock #锁前缀 默认配置
    primary-executor: com.wjk.kylin.lock.executor.redisson.RedissonLockExecutor #默认执行器。默认redisson>zookeeper
    redisson: true              #是否开启redisson 默认true
    zookeeper:
      zk-servers: 127.0.0.1:2181 #zk的server地址,多个server之间使用英文逗号分隔开 。配置地址则开启zookeeper
      session-timeout: 60000     #会话超时时间,默认值60000 单位:毫秒
      connection-timeout: 15000  #连接超时时间,默认值15000 单位:毫秒
      base-sleep-time-ms: 5000   #初始sleep时间,默认值5000 单位:毫秒
      max-retries: 3             #最大失败重试次数
      namespace: curator/kylin/lock #命名空间

2.2.2、redisson.yml

# 单节点配置
singleServerConfig:
  # 连接空闲超时,单位:毫秒
  idleConnectionTimeout: 10000
  # 连接超时,单位:毫秒
  connectTimeout: 10000
  # 命令等待超时,单位:毫秒
  timeout: 3000
  # 命令失败重试次数,如果尝试达到 retryAttempts(命令失败重试次数) 仍然不能将命令发送至某个指定的节点时,将抛出错误。
  # 如果尝试在此限制之内发送成功,则开始启用 timeout(命令等待超时) 计时。
  retryAttempts: 3
  # 命令重试发送时间间隔,单位:毫秒
  retryInterval: 1500
  # 密码
  password: redis123
  # 单个连接最大订阅数量
  subscriptionsPerConnection: 5
  # 客户端名称
  #clientName: axin
  #  # 节点地址
  address: redis://127.0.0.1:6379
  # 发布和订阅连接的最小空闲连接数
  subscriptionConnectionMinimumIdleSize: 1
  # 发布和订阅连接池大小
  subscriptionConnectionPoolSize: 50
  # 最小空闲连接数
  connectionMinimumIdleSize: 32
  # 连接池大小
  connectionPoolSize: 64
  # 数据库编号
  database: 2
  # DNS监测时间间隔,单位:毫秒
  dnsMonitoringInterval: 5000
# 线程池数量,默认值: 当前处理核数量 * 2
#threads: 0
# Netty线程池数量,默认值: 当前处理核数量 * 2
#nettyThreads: 0
# 编码
codec: ! {}
# 传输模式
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、自定义加锁失败执行方法

//加锁失败,会调用 DemoLockFailureCallBack中方法名称、参数类型列表相同的方法
@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;
    }
}
展开阅读全文

页面更新:2024-04-25

标签:分布式   联锁   注解   线程   加锁   命令   数量   单位   时间   方法

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top