diff --git a/doc/sql/easy_retry.sql b/doc/sql/easy_retry.sql index ec4b3d4fd..0cd88fcf2 100644 --- a/doc/sql/easy_retry.sql +++ b/doc/sql/easy_retry.sql @@ -161,7 +161,7 @@ CREATE TABLE `server_node` ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COMMENT='服务器节点' ; -CREATE TABLE `shedlock` +CREATE TABLE `distributed_lock` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', `name` varchar(64) NOT NULL COMMENT '锁名称', diff --git a/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/config/ShedlockConfig.java b/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/config/ShedlockConfig.java index b4e04ab34..8567aa61f 100644 --- a/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/config/ShedlockConfig.java +++ b/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/config/ShedlockConfig.java @@ -22,7 +22,7 @@ import java.util.TimeZone; @EnableSchedulerLock(defaultLockAtMostFor = "PT30S") public class ShedlockConfig { - @Bean +// @Bean public LockProvider lockProvider(DataSource dataSource) { return new JdbcTemplateLockProvider( JdbcTemplateLockProvider.Configuration.builder() @@ -32,7 +32,7 @@ public class ShedlockConfig { ); } - @Bean +// @Bean public TaskScheduler scheduledExecutorService() { ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.setPoolSize(2); diff --git a/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/persistence/mybatis/mapper/DistributedLockMapper.java b/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/persistence/mybatis/mapper/DistributedLockMapper.java new file mode 100644 index 000000000..e29f7c86a --- /dev/null +++ b/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/persistence/mybatis/mapper/DistributedLockMapper.java @@ -0,0 +1,16 @@ +package com.aizuda.easy.retry.server.persistence.mybatis.mapper; + +import com.aizuda.easy.retry.server.persistence.mybatis.po.DistributedLock; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 锁定表 Mapper 接口 + *

+ * + * @author www.byteblogs.com + * @since 2023-07-20 + */ +public interface DistributedLockMapper extends BaseMapper { + +} diff --git a/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/persistence/mybatis/po/DistributedLock.java b/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/persistence/mybatis/po/DistributedLock.java new file mode 100644 index 000000000..b9033d449 --- /dev/null +++ b/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/persistence/mybatis/po/DistributedLock.java @@ -0,0 +1,63 @@ +package com.aizuda.easy.retry.server.persistence.mybatis.po; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; +import lombok.Getter; +import lombok.Setter; + +/** + *

+ * 锁定表 + *

+ * + * @author www.byteblogs.com + * @since 2023-07-20 + */ +@Getter +@Setter +@TableName("distributed_lock") +public class DistributedLock implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 锁名称 + */ + private String name; + + /** + * 锁定时长 + */ + private LocalDateTime lockUntil; + + /** + * 锁定时间 + */ + private LocalDateTime lockedAt; + + /** + * 锁定者 + */ + private String lockedBy; + + /** + * 创建时间 + */ + private LocalDateTime createDt; + + /** + * 修改时间 + */ + private LocalDateTime updateDt; + + +} diff --git a/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/persistence/support/Access.java b/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/persistence/support/Access.java new file mode 100644 index 000000000..591d1d9e2 --- /dev/null +++ b/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/persistence/support/Access.java @@ -0,0 +1,11 @@ +package com.aizuda.easy.retry.server.persistence.support; + +/** + * @author www.byteblogs.com + * @date 2023-07-20 22:47:57 + * @since 2.1.0 + */ +public interface Access { + + boolean supports(int type); +} diff --git a/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/persistence/support/LockAccess.java b/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/persistence/support/LockAccess.java new file mode 100644 index 000000000..715ae9f28 --- /dev/null +++ b/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/persistence/support/LockAccess.java @@ -0,0 +1,19 @@ +package com.aizuda.easy.retry.server.persistence.support; + +import net.javacrumbs.shedlock.core.LockConfiguration; +import org.jetbrains.annotations.NotNull; + +/** + * @author www.byteblogs.com + * @date 2023-07-20 22:45:41 + * @since 2.1.0 + */ +public interface LockAccess extends Access { + + boolean insertRecord(); + + boolean updateRecord(); + + void unlock(); + +} diff --git a/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/persistence/support/access/lock/AbstractLockAccess.java b/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/persistence/support/access/lock/AbstractLockAccess.java new file mode 100644 index 000000000..ddcbc1248 --- /dev/null +++ b/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/persistence/support/access/lock/AbstractLockAccess.java @@ -0,0 +1,11 @@ +package com.aizuda.easy.retry.server.persistence.support.access.lock; + +import com.aizuda.easy.retry.server.persistence.support.LockAccess; + +/** + * @author www.byteblogs.com + * @date 2023-07-20 22:46:14 + * @since + */ +public abstract class AbstractLockAccess implements LockAccess { +} diff --git a/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/support/cache/CacheLockRecord.java b/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/support/cache/CacheLockRecord.java new file mode 100644 index 000000000..911da62d9 --- /dev/null +++ b/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/support/cache/CacheLockRecord.java @@ -0,0 +1,52 @@ +package com.aizuda.easy.retry.server.support.cache; + +import akka.actor.ActorRef; +import com.aizuda.easy.retry.common.core.log.LogUtils; +import com.aizuda.easy.retry.server.support.Lifecycle; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import lombok.extern.slf4j.Slf4j; + +import java.util.Collections; +import java.util.Set; +import java.util.WeakHashMap; + +/** + * @author www.byteblogs.com + * @date 2023-07-20 22:53:21 + * @since 2.1.0 + */ +@Slf4j +public class CacheLockRecord implements Lifecycle { + private static Cache CACHE; + + public static void addLockRecord(String lockName) { + CACHE.put(lockName, lockName); + } + + public static boolean lockRecordRecentlyCreated(String lockName) { + return CACHE.asMap().containsKey(lockName); + } + + public static long getSize() { + return CACHE.size(); + } + + public static void clear() { + CACHE.invalidateAll(); + } + + @Override + public void start() { + LogUtils.info(log, "CacheLockRecord start"); + CACHE = CacheBuilder.newBuilder() + // 设置并发级别为cpu核心数 + .concurrencyLevel(Runtime.getRuntime().availableProcessors()) + .build(); + } + + @Override + public void close() { + + } +} diff --git a/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/support/handler/DistributedLockHandler.java b/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/support/handler/DistributedLockHandler.java new file mode 100644 index 000000000..b5a0a9114 --- /dev/null +++ b/easy-retry-server/src/main/java/com/aizuda/easy/retry/server/support/handler/DistributedLockHandler.java @@ -0,0 +1,34 @@ +package com.aizuda.easy.retry.server.support.handler; + +import com.aizuda.easy.retry.server.persistence.mybatis.mapper.DistributedLockMapper; +import com.aizuda.easy.retry.server.persistence.support.LockAccess; +import com.aizuda.easy.retry.server.support.cache.CacheLockRecord; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @author www.byteblogs.com + * @date 2023-07-20 22:28:35 + * @since 2.1.0 + */ +@Component +public class DistributedLockHandler { + @Autowired + private LockAccess lockAccess; + + public boolean lock(String lockName) { + // 先本地缓存锁定信息 + if (!CacheLockRecord.lockRecordRecentlyCreated(lockName)) { + if (lockAccess.insertRecord()) { + CacheLockRecord.addLockRecord(lockName); + return true; + } + // we were not to create the record, it already exists, let's put it to the cache so we do not try again + CacheLockRecord.addLockRecord(lockName); + } + + return lockAccess.updateRecord(); + } + + +} diff --git a/easy-retry-server/src/main/resources/mapper/DistributedLockMapper.xml b/easy-retry-server/src/main/resources/mapper/DistributedLockMapper.xml new file mode 100644 index 000000000..958e6cd99 --- /dev/null +++ b/easy-retry-server/src/main/resources/mapper/DistributedLockMapper.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + id, name, lock_until, locked_at, locked_by, create_dt, update_dt + + +