From 3188a40da3c801bec3dfc92daa8d828d92b18c78 Mon Sep 17 00:00:00 2001 From: stylefeng Date: Thu, 19 Sep 2024 21:54:08 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=908.1.9=E3=80=91=E3=80=90lock=E3=80=91?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E5=88=86=E5=B8=83=E5=BC=8F=E9=94=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel-d-lock/README.md | 1 + kernel-d-lock/lock-api/README.md | 1 + kernel-d-lock/lock-api/pom.xml | 16 ++ .../roses/kernel/lock/api/KernelLock.java | 33 ++++ .../kernel/lock/api/KernelLockClient.java | 23 +++ kernel-d-lock/lock-sdk-redisson/pom.xml | 32 ++++ .../lock/redisson/RedissonKernelClient.java | 28 +++ .../lock/redisson/RedissonKernelLock.java | 32 ++++ .../lock-spring-boot-starter-redisson/pom.xml | 21 ++ .../ProjectLockCacheAutoConfiguration.java | 179 ++++++++++++++++++ .../main/resources/META-INF/spring.factories | 2 + kernel-d-lock/pom.xml | 31 +++ pom.xml | 4 + 13 files changed, 403 insertions(+) create mode 100644 kernel-d-lock/README.md create mode 100644 kernel-d-lock/lock-api/README.md create mode 100644 kernel-d-lock/lock-api/pom.xml create mode 100644 kernel-d-lock/lock-api/src/main/java/cn/stylefeng/roses/kernel/lock/api/KernelLock.java create mode 100644 kernel-d-lock/lock-api/src/main/java/cn/stylefeng/roses/kernel/lock/api/KernelLockClient.java create mode 100644 kernel-d-lock/lock-sdk-redisson/pom.xml create mode 100644 kernel-d-lock/lock-sdk-redisson/src/main/java/cn/stylefeng/roses/kernel/lock/redisson/RedissonKernelClient.java create mode 100644 kernel-d-lock/lock-sdk-redisson/src/main/java/cn/stylefeng/roses/kernel/lock/redisson/RedissonKernelLock.java create mode 100644 kernel-d-lock/lock-spring-boot-starter-redisson/pom.xml create mode 100644 kernel-d-lock/lock-spring-boot-starter-redisson/src/main/java/cn/stylefeng/roses/kernel/lock/starter/ProjectLockCacheAutoConfiguration.java create mode 100644 kernel-d-lock/lock-spring-boot-starter-redisson/src/main/resources/META-INF/spring.factories create mode 100644 kernel-d-lock/pom.xml diff --git a/kernel-d-lock/README.md b/kernel-d-lock/README.md new file mode 100644 index 000000000..9c638a5ed --- /dev/null +++ b/kernel-d-lock/README.md @@ -0,0 +1 @@ +锁模块-提供分布式锁的支持 \ No newline at end of file diff --git a/kernel-d-lock/lock-api/README.md b/kernel-d-lock/lock-api/README.md new file mode 100644 index 000000000..ce7129ccd --- /dev/null +++ b/kernel-d-lock/lock-api/README.md @@ -0,0 +1 @@ +锁模块-分布式锁的接口 \ No newline at end of file diff --git a/kernel-d-lock/lock-api/pom.xml b/kernel-d-lock/lock-api/pom.xml new file mode 100644 index 000000000..793aee0cd --- /dev/null +++ b/kernel-d-lock/lock-api/pom.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + com.gunsdevops + kernel-d-lock + 8.1.9 + ../pom.xml + + + lock-api + jar + + \ No newline at end of file diff --git a/kernel-d-lock/lock-api/src/main/java/cn/stylefeng/roses/kernel/lock/api/KernelLock.java b/kernel-d-lock/lock-api/src/main/java/cn/stylefeng/roses/kernel/lock/api/KernelLock.java new file mode 100644 index 000000000..9ddb02364 --- /dev/null +++ b/kernel-d-lock/lock-api/src/main/java/cn/stylefeng/roses/kernel/lock/api/KernelLock.java @@ -0,0 +1,33 @@ +package cn.stylefeng.roses.kernel.lock.api; + +import java.util.concurrent.TimeUnit; + +/** + * 分布式锁对象接口 + * + * @author yaoliguo + * @since 2024-09-12 14:25 + */ +public interface KernelLock { + + /** + * 尝试获取定义了获取锁 + * + * @param waitTime 获取锁的最大时间 + * @param leaseTime 租约时间 单位时间单位 + * @return true-锁被成功获取,false-锁已经设置 + * @throws InterruptedException 如果线程被中断 + * @author yaoliguo + * @since 2024-09-12 14:25 + */ + boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException; + + /** + * 释放锁 + * + * @author yaoliguo + * @since 2024-09-12 14:25 + */ + void unlock(); + +} diff --git a/kernel-d-lock/lock-api/src/main/java/cn/stylefeng/roses/kernel/lock/api/KernelLockClient.java b/kernel-d-lock/lock-api/src/main/java/cn/stylefeng/roses/kernel/lock/api/KernelLockClient.java new file mode 100644 index 000000000..f2249f528 --- /dev/null +++ b/kernel-d-lock/lock-api/src/main/java/cn/stylefeng/roses/kernel/lock/api/KernelLockClient.java @@ -0,0 +1,23 @@ +package cn.stylefeng.roses.kernel.lock.api; + +/** + * 获取锁的客户端 + * + * @author yaoliguo + * @since 2024-09-12 15:45 + */ +public interface KernelLockClient { + + /** + * 按名称返回锁实例 + *

+ * 实现非公平锁定,因此不保证线程的获取顺序 + * + * @param name 名称——对象的名称 + * @return 锁对象 + * @author yaoliguo + * @since 2024-09-12 15:45 + */ + KernelLock getLock(String name); + +} diff --git a/kernel-d-lock/lock-sdk-redisson/pom.xml b/kernel-d-lock/lock-sdk-redisson/pom.xml new file mode 100644 index 000000000..83eaabf45 --- /dev/null +++ b/kernel-d-lock/lock-sdk-redisson/pom.xml @@ -0,0 +1,32 @@ + + 4.0.0 + + com.gunsdevops + kernel-d-lock + 8.1.9 + ../pom.xml + + + lock-sdk-redisson + lock-sdk-redisson + jar + + + + + + com.gunsdevops + lock-api + ${roses.version} + + + + + org.redisson + redisson + ${redisson.version} + + + + diff --git a/kernel-d-lock/lock-sdk-redisson/src/main/java/cn/stylefeng/roses/kernel/lock/redisson/RedissonKernelClient.java b/kernel-d-lock/lock-sdk-redisson/src/main/java/cn/stylefeng/roses/kernel/lock/redisson/RedissonKernelClient.java new file mode 100644 index 000000000..6da52f988 --- /dev/null +++ b/kernel-d-lock/lock-sdk-redisson/src/main/java/cn/stylefeng/roses/kernel/lock/redisson/RedissonKernelClient.java @@ -0,0 +1,28 @@ +package cn.stylefeng.roses.kernel.lock.redisson; + +import cn.stylefeng.roses.kernel.lock.api.KernelLock; +import cn.stylefeng.roses.kernel.lock.api.KernelLockClient; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; + +/** + * 分布式锁的redisson的客户端 + * + * @author yaoliguo + * @since 2024-09-12 15:52 + */ +public class RedissonKernelClient implements KernelLockClient { + + private final RedissonClient redissonClient; + + public RedissonKernelClient(RedissonClient redissonClient) { + this.redissonClient = redissonClient; + } + + @Override + public KernelLock getLock(String name) { + RLock lock = redissonClient.getLock(name); + return new RedissonKernelLock(lock); + } + +} diff --git a/kernel-d-lock/lock-sdk-redisson/src/main/java/cn/stylefeng/roses/kernel/lock/redisson/RedissonKernelLock.java b/kernel-d-lock/lock-sdk-redisson/src/main/java/cn/stylefeng/roses/kernel/lock/redisson/RedissonKernelLock.java new file mode 100644 index 000000000..571b9bc1e --- /dev/null +++ b/kernel-d-lock/lock-sdk-redisson/src/main/java/cn/stylefeng/roses/kernel/lock/redisson/RedissonKernelLock.java @@ -0,0 +1,32 @@ +package cn.stylefeng.roses.kernel.lock.redisson; + +import cn.stylefeng.roses.kernel.lock.api.KernelLock; +import org.redisson.api.RLock; + +import java.util.concurrent.TimeUnit; + +/** + * 基于RedissonLock的实现 + * + * @author yaoliguo + * @since 2024-09-12 15:13 + */ +public class RedissonKernelLock implements KernelLock { + + private final RLock lock; + + public RedissonKernelLock(RLock lock) { + this.lock = lock; + } + + @Override + public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException { + return lock.tryLock(waitTime, leaseTime, unit); + } + + @Override + public void unlock() { + lock.unlock(); + } + +} diff --git a/kernel-d-lock/lock-spring-boot-starter-redisson/pom.xml b/kernel-d-lock/lock-spring-boot-starter-redisson/pom.xml new file mode 100644 index 000000000..3f504422c --- /dev/null +++ b/kernel-d-lock/lock-spring-boot-starter-redisson/pom.xml @@ -0,0 +1,21 @@ + + 4.0.0 + + com.gunsdevops + kernel-d-lock + 8.1.9 + ../pom.xml + + lock-spring-boot-starter-redisson + jar + + + + com.gunsdevops + lock-sdk-redisson + ${roses.version} + + + + diff --git a/kernel-d-lock/lock-spring-boot-starter-redisson/src/main/java/cn/stylefeng/roses/kernel/lock/starter/ProjectLockCacheAutoConfiguration.java b/kernel-d-lock/lock-spring-boot-starter-redisson/src/main/java/cn/stylefeng/roses/kernel/lock/starter/ProjectLockCacheAutoConfiguration.java new file mode 100644 index 000000000..ee3105dd5 --- /dev/null +++ b/kernel-d-lock/lock-spring-boot-starter-redisson/src/main/java/cn/stylefeng/roses/kernel/lock/starter/ProjectLockCacheAutoConfiguration.java @@ -0,0 +1,179 @@ +package cn.stylefeng.roses.kernel.lock.starter; + +import cn.hutool.core.util.ObjectUtil; +import cn.stylefeng.roses.kernel.lock.redisson.RedissonKernelClient; +import lombok.extern.slf4j.Slf4j; +import org.redisson.Redisson; +import org.redisson.api.RedissonClient; +import org.redisson.client.codec.StringCodec; +import org.redisson.config.Config; +import org.redisson.config.ReadMode; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 项目锁的redisson配置 + * + * @author yaoliguo + * @since 2024/9/19 21:29 + */ +@Configuration +@Slf4j +public class ProjectLockCacheAutoConfiguration { + + /** + * Redis服务器地址 + */ + @Value("${spring.redis.host}") + private String host; + + /** + * Redis端口 + */ + @Value("${spring.redis.port}") + private String port; + + /** + * Redis密码 + */ + @Value("${spring.redis.password:}") + private String password; + + /** + * Sentinel 节点列表 + */ + @Value("${spring.redisson.sentinel.nodes:}") + private String sentinel; + + /** + * Sentinel 模式中的主节点名称 + */ + @Value("${spring.redisson.sentinel.master:}") + private String masterName; + + /** + * Redis 集群模式中的节点列表 + */ + @Value("${spring.redisson.cluster:}") + private String cluster; + + /** + * 超时时间,单位:毫秒 + */ + private final int REDIS_RESPONSE_MILLISECONDS = 2000; + + /** + * 扫描间隔,单位:毫秒 + */ + private final int REDIS_CLUSTER_SCAN_INTERVAL = 60000; + + /** + * redis地址前缀 + */ + private static final String ADDRESS_PREFIX = "redis://"; + + /** + * 初始化Redisson客户端 + * + * @author fengshuonan + * @since 2024/9/19 21:48 + */ + @Bean + public RedissonClient myRedissonClient() { + + // 哨兵模式 + if (ObjectUtil.isNotEmpty(sentinel)) { + log.info("redis is sentinel mode"); + return redissonSentinel(); + } + + // 集群模式 + if (ObjectUtil.isNotEmpty(cluster)) { + log.info("redis is cluster mode"); + return redissonCluster(); + } + + // 单机模式 + if (ObjectUtil.isNotEmpty(host)) { + log.info("redis is single mode"); + return redissonSingle(); + } + + log.error("redisson config can not support this redis mode"); + + return null; + } + + /** + * 初始化锁获取 + * + * @author fengshuonan + * @since 2024/9/19 21:52 + */ + @Bean + public RedissonKernelClient RedissonKernelClient(RedissonClient redissonClient) { + return new RedissonKernelClient(redissonClient); + } + + /** + * 初始化Redisson:单机模式 + * + * @author fengshuonan + * @since 2024/9/19 21:52 + */ + private RedissonClient redissonSingle() { + Config config = new Config(); + String address = ADDRESS_PREFIX + host + ":" + port; + // 设置 + config.setCodec(new StringCodec()) + // 这是用的集群server + .useSingleServer().setAddress(address).setTimeout(REDIS_RESPONSE_MILLISECONDS).setPassword(password); + return Redisson.create(config); + } + + /** + * 初始化Redisson:哨兵模式 + * + * @author fengshuonan + * @since 2024/9/19 21:52 + */ + private RedissonClient redissonSentinel() { + + String[] nodes = sentinel.split(","); + // redisson版本是3.5,集群的ip前面要加上“redis://”,不然会报错,3.2版本可不加 + for (int i = 0; i < nodes.length; i++) { + nodes[i] = ADDRESS_PREFIX + nodes[i]; + } + Config config = new Config(); + // 设置 + config.setCodec(new StringCodec()).useSentinelServers().setMasterName(masterName).setPassword(password).setTimeout(REDIS_RESPONSE_MILLISECONDS).addSentinelAddress(nodes) + // 在Redisson启动期间启用sentinels列表检查,默认为true,这里我们设置为false,不检查 + .setCheckSentinelsList(false); + return Redisson.create(config); + } + + /** + * 初始化Redisson:集群模式 + * + * @author fengshuonan + * @since 2024/9/19 21:52 + */ + private RedissonClient redissonCluster() { + String[] nodes = cluster.split(","); + // redisson版本是3.5,集群的ip前面要加上“redis://”,不然会报错,3.2版本可不加 + for (int i = 0; i < nodes.length; i++) { + nodes[i] = ADDRESS_PREFIX + nodes[i]; + } + Config config = new Config(); + // 设置 + config.setCodec(new StringCodec()) + // 这是用的集群server + .useClusterServers() + // 设置集群状态扫描时间 + .setScanInterval(REDIS_CLUSTER_SCAN_INTERVAL).addNodeAddress(nodes).setPassword(password).setReadMode(ReadMode.MASTER); + ; + return Redisson.create(config); + } + +} diff --git a/kernel-d-lock/lock-spring-boot-starter-redisson/src/main/resources/META-INF/spring.factories b/kernel-d-lock/lock-spring-boot-starter-redisson/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000..2543b58b4 --- /dev/null +++ b/kernel-d-lock/lock-spring-boot-starter-redisson/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + cn.stylefeng.roses.kernel.lock.starter.ProjectLockCacheAutoConfiguration \ No newline at end of file diff --git a/kernel-d-lock/pom.xml b/kernel-d-lock/pom.xml new file mode 100644 index 000000000..ac008b85b --- /dev/null +++ b/kernel-d-lock/pom.xml @@ -0,0 +1,31 @@ + + 4.0.0 + + com.javaguns.roses + roses-kernel + 8.1.9 + ../pom.xml + + + com.gunsdevops + kernel-d-lock + pom + + kernel-d-lock + + + lock-api + lock-sdk-redisson + lock-spring-boot-starter-redisson + + + + + com.javaguns.roses + kernel-a-rule + ${roses.version} + + + + diff --git a/pom.xml b/pom.xml index a2ea69662..4b7c47e15 100644 --- a/pom.xml +++ b/pom.xml @@ -103,6 +103,9 @@ kernel-s-user-favorite + + kernel-d-lock + @@ -143,6 +146,7 @@ 2.2.6.RELEASE 1.78.1 7.1.1 + 3.18.0