一个强大的分布式锁框架——Lock4j

一、简介

Lock4j是一个分布式锁组件,它提供了多种不同的支持以满足不同性能和环境的需求,基于Spring AOP的声明式和编程式分布式锁,支持RedisTemplate、Redisson、Zookeeper。

二、特性

• 简单易用,功能强大,扩展性强。

• 支持redission, redisTemplate, zookeeper,可混用,支持扩展。

开源地址:

https://gitee.com/baomidou/lock4j

三、使用前准备
3.1 引入依赖

<!-- Lock4j -->
<!-- 若使用redisTemplate作为分布式锁底层,则需要引入 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>lock4j-redis-template-spring-boot-starter</artifactId>
<version>2.2.4</version>
</dependency>
<!-- 若使用redisson作为分布式锁底层,则需要引入 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>lock4j-redisson-spring-boot-starter</artifactId>
<version>2.2.4</version>
</dependency>

3.2 添加redis配置

spring:
  redis:
database:0
 Redis服务器地址 写你的ip
host:127.0.0.1
Redis服务器连接端口
port:6379
Redis服务器连接密码(默认为空)
password:
连接池最大连接数(使用负值表示没有限制  类似于mysql的连接池
jedis:
pool:
max-active:200
连接池最大阻塞等待时间(使用负值表示没有限制) 表示连接池的链接拿完了 现在去申请需要等待的时间
max-wait:-1
连接池中的最大空闲连接
max-idle:10
连接池中的最小空闲连接
min-idle:0
连接超时时间(毫秒) 去链接redis服务端
timeout: 6000

四、注解属性介绍

package com.baomidou.lock.annotation;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public@interfaceLock4j{
Stringname()default"";

Class<?extendsLockExecutor> executor()defaultLockExecutor.class;

String[] keys()default{""};

longexpire()default-1L;

longacquireTimeout()default-1L;

booleanautoRelease()defaulttrue;
}
```![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/6b1e6f4bbbe74069936e13d53233e80b.png)
### 五、简单使用

```java
@GetMapping("/lockMethod")
@Lock4j(keys = {"#key"}, acquireTimeout = 1000, expire = 10000)
publicResultlockMethod(@RequestParam String key){
ThreadUtil.sleep(5000);
returnResult.OK(key);
}

异常,通过全局异常处理返回如下结果:

{
"success":false,
"message":"操作失败,request failed,please retry it.",
"code":500,
"result":null,
"timestamp":1678866034929
}

六、高级使用

6.1 自定义执行器Exector

/**
 * 自定义分布式锁执行器
 *
 * @author: austin
 * @since: 2023/3/15 15:45
 */
@Component
publicclassCustomRedissonLockExecutorextendsAbstractLockExecutor{

@Override
publicObjectacquire(String lockKey, String lockValue, long expire, long acquireTimeout){
returnnull;
}

@Override
publicbooleanreleaseLock(String key, String value, Object lockInstance){
returnfalse;
}
}
在注解上直接指定特定的执行器:

@Lock4j(executor = CustomRedissonLockExecutor.class)

6.2 自定义分布式锁key生成器

/**
 * 自定义分布式锁key生成器
 *
 * @author: austin
 * @since: 2023/3/15 15:46
 */
@Component
publicclassCustomKeyBuilderextendsDefaultLockKeyBuilder{

publicCustomKeyBuilder(BeanFactory beanFactory){
super(beanFactory);
}
}

6.3 自定义抢占锁失败执行策略

/**
 * 自定义抢占锁失败执行策略
 *
 * @author: austin
 * @since: 2023/3/15 15:49
 */
@Component
publicclassGrabLockFailureStrategyimplementsLockFailureStrategy{

@Override
publicvoidonLockFailure(String key, Method method, Object[] arguments){

}
}
默认的锁获取失败策略为 

com.baomidou.lock.DefaultLockFailureStrategy.

6.4 手动加锁释放锁

@Service
publicclassLockServiceImplimplementsLockService{

@Autowired
privateLockTemplate lockTemplate;

@Override
publicvoidlock(String resourceKey){

LockInfolock= lockTemplate.lock(resourceKey,10000L,2000L,CustomRedissonLockExecutor.class);
if(lock ==null){
// 获取不到锁
thrownewFrameworkException("业务处理中,请稍后再试...");
}
// 获取锁成功,处理业务
try{
            doBusiness();
}catch(Exception e){
thrownewRuntimeException(e);
}finally{
            lockTemplate.releaseLock(lock);
}
}

privatevoiddoBusiness(){
// TODO 业务执行逻辑
}
}
### 分布式锁的概念 分布式锁是在分布式系统环境中用于控制多个节点对共享资源访问的一种机制[^2]。当多个不同的进程或线程运行在不同机器上时,这些进程可能需要协调对某些公共资源(如文件、数据库记录等)的独占性访问。此时就需要一种跨多台服务器的有效同步手段——即分布式锁。 #### 为什么需要使用分布式锁? 由于网络延迟和其他不确定性因素,在分布式的环境下直接依赖时间顺序来决定谁先获得资源是非常不可靠的做法。因此引入了分布式锁这一抽象层次,使得即使在网络分区的情况下也能够安全地管理临界区代码段,防止并发冲突的发生[^3]。 ### 实现原理 常见的几种实现方式如下: - **基于缓存的服务**:利用像 Redis 或 Memcached 这样的内存存储引擎作为中介来进行锁定操作。这类方案简单易行,但由于其本身可能存在数据不一致的情况,所以在高可用性和一致性方面有所欠缺[^5]。 - **基于 Zookeeper 的实现**:Zookeeper 提供了一套完整的 API 来创建临时节点并监听其他客户端对该节点的变化情况;通过这种方式可以在一组参与者之间达成共识从而完成加锁/解锁的过程。因为 Zookeeper 自身就是一个高度可靠的分布式协调服务框架,所以以此为基础构建出来的分布式锁具有较好的稳定性和安全性。 - **基于关系型数据库**:虽然传统的关系型数据库并不是专为解决此类问题而设计,但仍可通过一些技巧比如乐观锁(版本号)或者悲观锁(排他锁)等方式达到目的。不过考虑到效率低下以及潜在的竞争条件等问题,这种方法并不推荐广泛采用。 ```java // 使用Redisson库获取RedLock对象的一个例子 RLock lock = redissonClient.getLock("myDistributedLock"); try { boolean isLocked = lock.tryLock(10, TimeUnit.SECONDS); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { if(lock.isHeldByCurrentThread()){ lock.unlock(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值