# elegent-lock **Repository Path**: itliutong/elegent-lock ## Basic Information - **Project Name**: elegent-lock - **Description**: 这是一个基于springboot的优雅的分布式锁组件。使用这个组件可以让你更轻松、更优雅地在项目中集成分布式锁,让你更专注业务代码的开发 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-03-18 - **Last Updated**: 2024-03-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ![](doc/images/logob.png) # ElegentLock【分布式锁框架】 #### 介绍 这是一个基于springboot的优雅的分布式锁组件。使用这个组件可以让你更轻松、更优雅地在项目中集成分布式锁,让你更专注业务代码的开发。它目前支持redis分布式锁、redis红锁、consul分布式锁三种实现方式,可以通过更改配置自由切换而不需要更改业务代码。 #### 使用说明 ##### 准备工作 1.在项目中引入依赖 ```xml cn.elegent elegent-lock 1.0.0 ``` 2.在项目配置文件添加配置,示例如下: ```yaml elegent: lock: type: redis host: 127.0.0.1 port: 6379 ttl: 60 wait: 10 renewal: true ``` 配置说明: (1)type: 分布式锁类型,可选值:consul、redis、redlock,默认值是redis。 (2)host: 分布式锁中间件的部署地址,默认值为127.0.0.1。(类型为redlock此值无效) (3)port: 分布式锁中间件的端口,如果type为redis默认值6379,如果type为consul默认值8500。 (4)ttl: 分布式锁过期时间,单位秒,默认值60。 (5)wait: 等待超时时间,单位秒,默认值10。表示在获取不到锁的时候会在此时间内会进行重试。 (6)renewal:是否续期,默认值false。如果选择续期,则ttl值失效,分布式锁在到期前会自动续期。 (7)address: 地址列表。(类型为redlock此值生效) 示例如下: ``` 192.168.200.128:6379,127.0.0.1:6379,127.0.0.1:6380 ``` redlock(红锁)可以解决redis锁脑裂的问题,建议配置3和或5个节点。 ##### 加锁与释放锁 我们有两种方式实现分布式锁的加锁与释放锁,一种是代码方式实现,一种是注解方式实现。 ###### 代码方式 类中引入ELegentLock ```java @Autowired private ELegentLock eLegentLock; ``` 方法调用以下方法实现加锁与释放锁 ```java eLegentLock.tryLock(锁名字);//加锁,成功返回true,如果锁已经被占用则返回false eLegentLock.lock(锁名字);//加锁,如果锁被占用会通过自旋方式不断尝试,直到加成功为止。 eLegentLock.unLock(锁名字);//释放锁 ``` ###### 注解方式 在方法上添加注解`@ELegentLock(lockName = "test",always = true)` 即可。 `lockName`为锁名字,实际加锁会以`lockName`+方法参数作为锁key。 `always =true`,加锁,如果锁被占用会通过自旋方式不断尝试,直到加成功为止。 `always =false`,(默认值)加锁,只尝试一次。推荐使用此选项。 ##### 用户扩展 分布式锁框架目前提供了redis、红锁、consul三种分布式锁,用户也可以自行扩展,从而支持其它类型的分布式锁,例如ZK、mongoDB的分布式锁等等。那么用户如何扩展呢?步骤如下: (1)编写配置类,继承自LockConfig,参考以下代码: ```java @Configuration @ConditionalOnProperty(prefix = "elegent.lock",name = "type",havingValue = "XXXXX") @Data public class XXXXXLockConfig extends LockConfig{ /** * 主机ip */ @Value("${elegent.lock.host:127.0.0.1}") private String host; /** * 主机端口 */ @Value("${elegent.lock.port:8500}") private int port; } ``` havingValue指定的就是你想扩展的分布式锁名称,名字自定义。 (2)编写分布式锁实现类,实现ELegentLock接口,示例代码如下: ```java @ConditionalOnProperty(prefix = "elegent.lock",name = "type",havingValue = "consul") @Slf4j public class XXXXXLock implements ELegentLock { @Autowired private XXXXXLockConfig xxxxxLockConfig; @PostConstruct public void init(){ //todo: 初始化代码 } @Override public boolean tryLock(String lockName) { //todo: 编写一次性加锁逻辑 } @Override public boolean lock(String lockName) { while (true){ if(!isLocked(lockName)){ //如果没有被锁 if(tryLock(lockName, xxxxxLockConfig.getTtl())){ //尝试加锁 break;//一直到加锁成功才退出 } } try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } } return true; } @Override public boolean isLocked(String lockName) { //todo: 编写判断是否加锁逻辑 } /** * 释放锁 */ public boolean unLock(String lockName){ //todo: 编写释放锁逻辑 } } ``` #### 参与贡献 1. 从 `master` 分支 `checkout` 一个新分支(**注**:*请务必保证 master 代码是最新的*) 2. 新分支命名格式:`docs/username_description`,例如:`docs/tom_新增分布式锁配置项` 3. 在新分支上编辑文档、代码,并提交代码 4. 最后 `PR` 合并到 `develop` 分支,等待作者合并即可