diff --git a/demo-distributed-lock/demo-distributed-lock-curator/README.md b/demo-distributed-lock/demo-distributed-lock-curator/README.md
new file mode 100644
index 0000000..ad36ec0
--- /dev/null
+++ b/demo-distributed-lock/demo-distributed-lock-curator/README.md
@@ -0,0 +1,180 @@
+## spring-boot-demo-distributed-lock-curator
+
+> 此 demo 主要演示了 Spring Boot 如何基于 Curator 实现一个分布式锁
+
+## 1.开发步骤
+
+在 `demo-distributed-lock-api` 模块中,已经实现了基于 AOP 的分布式锁注解拦截、简单的扣减库存案例,因此本模块只需要实现以下两个接口即可。
+- `com.xkcoding.distributed.lock.api.DistributedLock`
+- `com.xkcoding.distributed.lock.api.DistributedLockClient`
+
+### 1.1.添加依赖
+
+```xml
+
+ * 启动器 + *
+ * + * @author yangkai.shen + * @date 2022-09-03 13:00 + */ +@SpringBootApplication +public class CuratorDistributedLockApplication { + + public static void main(String[] args) { + SpringApplication.run(CuratorDistributedLockApplication.class, args); + } + +} diff --git a/demo-distributed-lock/demo-distributed-lock-curator/src/main/java/com/xkcoding/distributed/lock/autoconfigure/CuratorDistributedLock.java b/demo-distributed-lock/demo-distributed-lock-curator/src/main/java/com/xkcoding/distributed/lock/autoconfigure/CuratorDistributedLock.java new file mode 100644 index 0000000..e33ef4a --- /dev/null +++ b/demo-distributed-lock/demo-distributed-lock-curator/src/main/java/com/xkcoding/distributed/lock/autoconfigure/CuratorDistributedLock.java @@ -0,0 +1,64 @@ +package com.xkcoding.distributed.lock.autoconfigure; + +import com.xkcoding.distributed.lock.api.DistributedLock; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.recipes.locks.InterProcessMutex; +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +/** + *+ * 基于 Curator 实现的分布式锁 + *
+ * + * @author yangkai.shen + * @date 2022-09-03 13:03 + */ +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); + } + } +} diff --git a/demo-distributed-lock/demo-distributed-lock-curator/src/main/java/com/xkcoding/distributed/lock/autoconfigure/CuratorDistributedLockAutoConfiguration.java b/demo-distributed-lock/demo-distributed-lock-curator/src/main/java/com/xkcoding/distributed/lock/autoconfigure/CuratorDistributedLockAutoConfiguration.java new file mode 100644 index 0000000..2d6eaaa --- /dev/null +++ b/demo-distributed-lock/demo-distributed-lock-curator/src/main/java/com/xkcoding/distributed/lock/autoconfigure/CuratorDistributedLockAutoConfiguration.java @@ -0,0 +1,38 @@ +package com.xkcoding.distributed.lock.autoconfigure; + +import lombok.extern.slf4j.Slf4j; +import org.apache.curator.RetryPolicy; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.CuratorFrameworkFactory; +import org.apache.curator.retry.ExponentialBackoffRetry; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + *+ * 基于Curator分布式锁自动装配类 + *
+ * + * @author yangkai.shen + * @date 2022-09-03 13:05 + */ +@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); + } +} diff --git a/demo-distributed-lock/demo-distributed-lock-curator/src/main/java/com/xkcoding/distributed/lock/autoconfigure/CuratorDistributedLockClient.java b/demo-distributed-lock/demo-distributed-lock-curator/src/main/java/com/xkcoding/distributed/lock/autoconfigure/CuratorDistributedLockClient.java new file mode 100644 index 0000000..383f30e --- /dev/null +++ b/demo-distributed-lock/demo-distributed-lock-curator/src/main/java/com/xkcoding/distributed/lock/autoconfigure/CuratorDistributedLockClient.java @@ -0,0 +1,34 @@ +package com.xkcoding.distributed.lock.autoconfigure; + +import com.xkcoding.distributed.lock.api.DistributedLock; +import com.xkcoding.distributed.lock.api.DistributedLockClient; +import lombok.RequiredArgsConstructor; +import org.apache.curator.framework.CuratorFramework; + +import java.util.concurrent.TimeUnit; + +/** + *+ * 获得一把 Curator 分布式锁 + *
+ * + * @author yangkai.shen + * @date 2022-09-03 13:04 + */ +@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); + } +} diff --git a/demo-distributed-lock/demo-distributed-lock-curator/src/main/resources/application.yml b/demo-distributed-lock/demo-distributed-lock-curator/src/main/resources/application.yml new file mode 100644 index 0000000..113bd15 --- /dev/null +++ b/demo-distributed-lock/demo-distributed-lock-curator/src/main/resources/application.yml @@ -0,0 +1,16 @@ +server: + port: 8080 + servlet: + context-path: /demo +spring: + sql: + init: + continue-on-error: true + mode: always + schema-locations: + - "classpath:db/schema.sql" + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/spring-boot-demo + username: root + password: root diff --git a/demo-distributed-lock/pom.xml b/demo-distributed-lock/pom.xml index ca50e17..f3112d5 100644 --- a/demo-distributed-lock/pom.xml +++ b/demo-distributed-lock/pom.xml @@ -20,10 +20,11 @@