feat: 2.1.0

1. 实现分布式锁实现未完待续
This commit is contained in:
byteblogs168 2023-07-20 23:02:06 +08:00
parent 7f9d6b5c7b
commit 82259df805
10 changed files with 230 additions and 3 deletions

View File

@ -161,7 +161,7 @@ CREATE TABLE `server_node`
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COMMENT='服务器节点' ) 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 '主键', `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(64) NOT NULL COMMENT '锁名称', `name` varchar(64) NOT NULL COMMENT '锁名称',

View File

@ -22,7 +22,7 @@ import java.util.TimeZone;
@EnableSchedulerLock(defaultLockAtMostFor = "PT30S") @EnableSchedulerLock(defaultLockAtMostFor = "PT30S")
public class ShedlockConfig { public class ShedlockConfig {
@Bean // @Bean
public LockProvider lockProvider(DataSource dataSource) { public LockProvider lockProvider(DataSource dataSource) {
return new JdbcTemplateLockProvider( return new JdbcTemplateLockProvider(
JdbcTemplateLockProvider.Configuration.builder() JdbcTemplateLockProvider.Configuration.builder()
@ -32,7 +32,7 @@ public class ShedlockConfig {
); );
} }
@Bean // @Bean
public TaskScheduler scheduledExecutorService() { public TaskScheduler scheduledExecutorService() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(2); scheduler.setPoolSize(2);

View File

@ -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;
/**
* <p>
* 锁定表 Mapper 接口
* </p>
*
* @author www.byteblogs.com
* @since 2023-07-20
*/
public interface DistributedLockMapper extends BaseMapper<DistributedLock> {
}

View File

@ -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;
/**
* <p>
* 锁定表
* </p>
*
* @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;
}

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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 {
}

View File

@ -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<String, String> 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() {
}
}

View File

@ -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();
}
}

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.aizuda.easy.retry.server.persistence.mybatis.mapper.DistributedLockMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.aizuda.easy.retry.server.persistence.mybatis.po.DistributedLock">
<id column="id" property="id" />
<result column="name" property="name" />
<result column="lock_until" property="lockUntil" />
<result column="locked_at" property="lockedAt" />
<result column="locked_by" property="lockedBy" />
<result column="create_dt" property="createDt" />
<result column="update_dt" property="updateDt" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, name, lock_until, locked_at, locked_by, create_dt, update_dt
</sql>
</mapper>