# distributed-lock-spring-boot-starter **Repository Path**: rayvinchen/distributed-lock-spring-boot-starter ## Basic Information - **Project Name**: distributed-lock-spring-boot-starter - **Description**: 分布式锁starter - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2021-01-11 - **Last Updated**: 2021-11-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # spring-boot-starter-distributed-lock #### 介绍 `spring-boot-starter-distributed-lock`是一个基于`baomidou/lock4j`增强的分布式锁组件,提供了zookeeper、redisson两种分布式锁的简单实现。 - `baomidou/lock4j`:https://gitee.com/baomidou/lock4j #### 特性 1. 简单易用,功能强大,扩展性强。 2. 支持redisson、zookeeper。可混用,支持扩展。 增强点: 1. 支持在接口上使用注解 - 如果一个接口有多种实现(如:es/mysql/mongo等不同取数逻辑),可以不必在3个实现都写一样的注解,直接在接口上打注解就可以 2. 支持lock与tryLock两种操作 #### 使用条件 1. spring-boot 版本:2.1.3以上 2. zookeeper的server、client版本:3.5.1之后,版本为3.5.1以前的话慎用,因为创建的父节点是永久节点,用于业务中可能会产生大量的无用永久节点。3.5.1之后新增的container节点更适合于分布式锁 #### 快速开始 1. 在需要使用分布式锁的项目中,引入分布式锁依赖 ```xml cn.blacksnow spring-boot-starter-distributed-lock ${version} org.redisson redisson-spring-boot-starter 3.10.7 org.apache.curator curator-recipes 4.3.0 org.apache.zookeeper zookeeper 3.5.7 ``` 2. 根据底层的配置需要,配置redis或者zookeeper ```yaml spring: redis: host: 127.0.0.1 ... distributed-lock: # 必填 application-name: distributed.lock.test zookeeper: # 如果是集群的话:127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183 address: 127.0.0.1:2181 ``` 3. 在需要分布式锁的地方使用Lock注解 ```java @Service public class UserServiceImpl implements UserService { @Lock(resource = "'A-' + #user.id", module = "user") public void sayHelloOnImpl(User user) { System.out.printf("userId: %s, sayHelloOnImpl%n", user.getId().toString()); } } public interface UserService { @Lock(resource = "'A-' + #user.id", module = "user") void sayHello(User user); } ``` 具体使用可以看测试用例 #### 高级使用 1. 配置 ```yaml distributed-lock: # 必填 application-name: distributed.lock.test # 默认的执行器 defaultExecutor: cn.blacksnow.distributed.lock.executor.RedissonLockExecutor # 全局默认过期时间(对zookeeper无用),单位:毫秒,默认3s expire-time: 3000 # 重试间隔时间,单位:毫秒,默认 200ms retry-interval: 200 # 获取锁的超时时间,单位:毫秒,默认3s acquire-timeout: 3000 # 全局默认注解加锁失败返回的信息 lock-failed-message: 有用户正在操作,请稍后再试 # zookeeper client相关配置 zookeeper: # 如果是集群的话:127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183 address: 127.0.0.1:2181 # 连接zookeeper最大重试次数,默认20 max-retries: 20 # 两次连接的睡眠时间,默认100ms sleep-time-ms: 100 ``` 2. 自定义锁key的生成器 ```java @Component public class CustomLockKeyBuilder implements LockKeyBuilder { private static final String PREFIX = "custom-builder:"; @Override public String buildKey(String applicationName, MethodInvocation invocation, Lock lockAnnotation) { return PREFIX + applicationName + ":" + invocation.getMethod().getDeclaringClass().getName() + "." + invocation.getMethod().getName() + ":" + lockAnnotation.module() + lockAnnotation.resource(); } } ``` 3. 锁注解属性 见confluence文档 4. 手动加解锁 ```java @Service public class UserServiceImpl implements UserService { @Autowired private LockTemplate lockTemplate; // other method ... @Override public void programmaticLock(Integer userId) { boolean locked = false; try { String lockKey = "distributed-lock:programmatic:P-" + userId; locked = lockTemplate.tryLock(lockKey, 6000, 5000); if (!locked) { throw new LockException("业务正在处理中,请稍后再试"); } System.out.println("编程式锁测试"); Thread.sleep(10000); } catch (LockException | InterruptedException exception) { throw new RuntimeException("业务正在处理中,请稍后再试"); } finally { if (locked) { lockTemplate.unlock(); } } } } ```