Are you sure you want to delete this task? Once this task is deleted, it cannot be recovered.
|
2 years ago | |
---|---|---|
.. | ||
src/main | 2 years ago | |
README.md | 2 years ago | |
docker-compose.env.yml | 2 years ago | |
pom.xml | 2 years ago |
此 demo 主要演示了 Spring Boot 如何基于 Curator 实现一个分布式锁
在 demo-distributed-lock-api
模块中,已经实现了基于 AOP 的分布式锁注解拦截、简单的扣减库存案例,因此本模块只需要实现以下两个接口即可。
com.xkcoding.distributed.lock.api.DistributedLock
com.xkcoding.distributed.lock.api.DistributedLockClient
<dependencies>
<dependency>
<groupId>com.xkcoding</groupId>
<artifactId>demo-distributed-lock-api</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${curator.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${curator.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
基于 Curator 实现分布式锁
public class CuratorDistributedLock extends DistributedLock {
private final CuratorFramework curatorFramework;
private final InterProcessMutex mutex;
private static final String ROOT_PATH = "/locks";
protected CuratorDistributedLock(CuratorFramework curatorFramework, String lockKey, long lockTime, TimeUnit timeUnit) {
super(lockKey, lockTime, timeUnit);
this.curatorFramework = curatorFramework;
mutex = new InterProcessMutex(curatorFramework, ROOT_PATH + "/" + lockKey);
}
@Override
public void lock() {
try {
mutex.acquire();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public boolean tryLock() {
try {
return tryLock(lockTime, timeUnit);
} catch (InterruptedException e) {
return false;
}
}
@Override
public boolean tryLock(long time, @NotNull TimeUnit unit) throws InterruptedException {
try {
return mutex.acquire(time, unit);
} catch (Exception e) {
return false;
}
}
@Override
public void unlock() {
try {
mutex.release();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
获取一把 Curator 分布式锁
@RequiredArgsConstructor
public class CuratorDistributedLockClient implements DistributedLockClient {
private final CuratorFramework curatorFramework;
/**
* 获取一把锁
*
* @param lockKey 锁的标识
* @param lockTime 锁的时间
* @param timeUnit 锁的时间单位
* @return 锁
*/
@Override
public DistributedLock getLock(String lockKey, long lockTime, TimeUnit timeUnit) {
return new CuratorDistributedLock(curatorFramework, lockKey, lockTime, timeUnit);
}
}
替换
demo-distributed-lock-api
中的默认实现
@Slf4j
@Configuration(proxyBeanMethods = false)
public class CuratorDistributedLockAutoConfiguration {
@Bean
public CuratorFramework curatorFramework() {
// 指数重试
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
// 创建 Curator
CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", retryPolicy);
// 启动 Curator
client.start();
log.info("===========> curator connected <===========");
return client;
}
@Bean
public CuratorDistributedLockClient distributedLockClient(CuratorFramework curatorFramework) {
return new CuratorDistributedLockClient(curatorFramework);
}
}
主要是 mysql 及 zookeeper 环境的搭建,这里我提供了 docker-compose 文件,方便同学们一键启动测试环境
$ cd demo-distributed-lock/demo-distributed-lock-curator
$ docker compose -f docker-compose.env.yml up
这里我通过 Apache Bench 进行模拟并发场景,我也构建了一个压测镜像 xkcoding/ab:alpine-3.16.2
,方便同学们进行快速测试
注意:每次启动项目,都会在重置库存,你也可以手动调用
/demo/stock/reset
接口重置
CuratorDistributedLockAutoConfiguration
类全部注释掉,这将不会装配 Curator 分布式锁CuratorDistributedLockApplication
docker run -it --rm xkcoding/ab:alpine-3.16.2 ab -n 5000 -c 100 http://${替换成你电脑的内网IP}:8080/demo/stock/reduce
CuratorDistributedLockAutoConfiguration
类的注释解开,此时 Spring Boot 会自动装配我们的 Redisson 分布式锁CuratorDistributedLockApplication
docker run -it --rm xkcoding/ab:alpine-3.16.2 ab -n 5000 -c 100 http://${替换成你电脑的内网IP}:8080/demo/stock/reduce
一个用来深度学习并实战 spring boot 的项目,目前总共包含 66 个集成demo,已经完成 55 个。
Java SVG CSS JavaScript SQL other