彻底移除 RedisKeyDefine
parent
8b704ff483
commit
0b17298963
|
@ -1,47 +0,0 @@
|
||||||
package cn.iocoder.yudao.framework.tenant.core.redis;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
|
||||||
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
|
|
||||||
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 多租户拓展的 RedisKeyDefine 实现类
|
|
||||||
*
|
|
||||||
* 由于 Redis 不同于 MySQL 有 column 字段,无法通过类似 WHERE tenant_id = ? 的方式过滤
|
|
||||||
* 所以需要通过在 Redis Key 上增加后缀的方式,进行租户之间的隔离。具体的步骤是:
|
|
||||||
* 1. 假设 Redis Key 是 user:%d,示例是 user:1;对应到多租户的 Redis Key 是 user:%d:%d,
|
|
||||||
* 2. 在 Redis DAO 中,需要使用 {@link #formatKey(Object...)} 方法,进行 Redis Key 的格式化
|
|
||||||
*
|
|
||||||
* 注意,大多数情况下,并不用使用 TenantRedisKeyDefine 实现。主要的使用场景,还是 Redis Key 可能存在冲突的情况。
|
|
||||||
* 例如说,租户 1 和 2 都有一个手机号作为 Key,则他们会存在冲突的问题
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
public class TenantRedisKeyDefine extends RedisKeyDefine {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 多租户的 KEY 模板
|
|
||||||
*/
|
|
||||||
private static final String KEY_TEMPLATE_SUFFIX = ":%d";
|
|
||||||
|
|
||||||
public TenantRedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType, Duration timeout) {
|
|
||||||
super(memo, buildKeyTemplate(keyTemplate), keyType, valueType, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TenantRedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType, TimeoutTypeEnum timeoutType) {
|
|
||||||
super(memo, buildKeyTemplate(keyTemplate), keyType, valueType, timeoutType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String buildKeyTemplate(String keyTemplate) {
|
|
||||||
return keyTemplate + KEY_TEMPLATE_SUFFIX;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String formatKey(Object... args) {
|
|
||||||
args = ArrayUtil.append(args, TenantContextHolder.getRequiredTenantId());
|
|
||||||
return super.formatKey(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
package cn.iocoder.yudao.framework.tenant.core.redis;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
|
|
||||||
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
class TenantRedisKeyDefineTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFormatKey() {
|
|
||||||
Long tenantId = 30L;
|
|
||||||
TenantContextHolder.setTenantId(tenantId);
|
|
||||||
// 准备参数
|
|
||||||
TenantRedisKeyDefine define = new TenantRedisKeyDefine("", "user:%d:%d", RedisKeyDefine.KeyTypeEnum.HASH,
|
|
||||||
Object.class, RedisKeyDefine.TimeoutTypeEnum.FIXED);
|
|
||||||
Long userId = 10L;
|
|
||||||
Integer userType = 1;
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
String key = define.formatKey(userId, userType);
|
|
||||||
// 断言
|
|
||||||
assertEquals("user:10:1:30", key);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,7 +1,5 @@
|
||||||
package cn.iocoder.yudao.framework.captcha.config;
|
package cn.iocoder.yudao.framework.captcha.config;
|
||||||
|
|
||||||
import cn.hutool.core.util.ClassUtil;
|
|
||||||
import cn.iocoder.yudao.framework.captcha.core.enums.CaptchaRedisKeyConstants;
|
|
||||||
import cn.iocoder.yudao.framework.captcha.core.service.RedisCaptchaServiceImpl;
|
import cn.iocoder.yudao.framework.captcha.core.service.RedisCaptchaServiceImpl;
|
||||||
import com.xingyuv.captcha.properties.AjCaptchaProperties;
|
import com.xingyuv.captcha.properties.AjCaptchaProperties;
|
||||||
import com.xingyuv.captcha.service.CaptchaCacheService;
|
import com.xingyuv.captcha.service.CaptchaCacheService;
|
||||||
|
@ -15,12 +13,6 @@ import javax.annotation.Resource;
|
||||||
@AutoConfiguration
|
@AutoConfiguration
|
||||||
public class YudaoCaptchaConfiguration {
|
public class YudaoCaptchaConfiguration {
|
||||||
|
|
||||||
static {
|
|
||||||
// 手动加载 Lock4jRedisKeyConstants 类,因为它不会被使用到
|
|
||||||
// 如果不加载,会导致 Redis 监控,看到它的 Redis Key 枚举
|
|
||||||
ClassUtil.loadClass(CaptchaRedisKeyConstants.class.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private StringRedisTemplate stringRedisTemplate;
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,5 @@
|
||||||
package cn.iocoder.yudao.framework.captcha.core.enums;
|
package cn.iocoder.yudao.framework.captcha.core.enums;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
|
|
||||||
import com.xingyuv.captcha.model.vo.PointVO;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.STRING;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证码 Redis Key 枚举类
|
* 验证码 Redis Key 枚举类
|
||||||
*
|
*
|
||||||
|
@ -14,12 +7,22 @@ import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.S
|
||||||
*/
|
*/
|
||||||
public interface CaptchaRedisKeyConstants {
|
public interface CaptchaRedisKeyConstants {
|
||||||
|
|
||||||
RedisKeyDefine AJ_CAPTCHA_REQ_LIMIT = new RedisKeyDefine("验证码的请求限流",
|
/**
|
||||||
"AJ.CAPTCHA.REQ.LIMIT-%s-%s",
|
* 验证码的请求限流
|
||||||
STRING, Integer.class, Duration.ofSeconds(60)); // 例如说:验证失败 5 次,get 接口锁定
|
*
|
||||||
|
* KEY 格式:AJ.CAPTCHA.REQ.LIMIT-%s-%s
|
||||||
|
* VALUE 数据类型:String // 例如说:验证失败 5 次,get 接口锁定
|
||||||
|
* 过期时间:60 秒
|
||||||
|
*/
|
||||||
|
String AJ_CAPTCHA_REQ_LIMIT = "AJ.CAPTCHA.REQ.LIMIT-%s-%s";
|
||||||
|
|
||||||
RedisKeyDefine AJ_CAPTCHA_RUNNING = new RedisKeyDefine("验证码的坐标",
|
/**
|
||||||
"RUNNING:CAPTCHA:%s", // AbstractCaptchaService.REDIS_CAPTCHA_KEY
|
* 验证码的坐标
|
||||||
STRING, PointVO.class, Duration.ofSeconds(120)); // {"secretKey":"PP1w2Frr2KEejD2m","x":162,"y":5}
|
*
|
||||||
|
* KEY 格式:RUNNING:CAPTCHA:%s // AbstractCaptchaService.REDIS_CAPTCHA_KEY
|
||||||
|
* VALUE 数据类型:String // PointVO.class {"secretKey":"PP1w2Frr2KEejD2m","x":162,"y":5}
|
||||||
|
* 过期时间:120 秒
|
||||||
|
*/
|
||||||
|
String AJ_CAPTCHA_RUNNING = "RUNNING:CAPTCHA:%s";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
package cn.iocoder.yudao.framework.idempotent.core.redis;
|
package cn.iocoder.yudao.framework.idempotent.core.redis;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.STRING;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 幂等 Redis DAO
|
* 幂等 Redis DAO
|
||||||
*
|
*
|
||||||
|
@ -16,9 +13,14 @@ import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.S
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class IdempotentRedisDAO {
|
public class IdempotentRedisDAO {
|
||||||
|
|
||||||
private static final RedisKeyDefine IDEMPOTENT = new RedisKeyDefine("幂等操作",
|
/**
|
||||||
"idempotent:%s", // 参数为 uuid
|
* 幂等操作
|
||||||
STRING, String.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC);
|
*
|
||||||
|
* KEY 格式:idempotent:%s // 参数为 uuid
|
||||||
|
* VALUE 格式:String
|
||||||
|
* 过期时间:不固定
|
||||||
|
*/
|
||||||
|
private static final String IDEMPOTENT = "idempotent:%s";
|
||||||
|
|
||||||
private final StringRedisTemplate redisTemplate;
|
private final StringRedisTemplate redisTemplate;
|
||||||
|
|
||||||
|
@ -28,7 +30,7 @@ public class IdempotentRedisDAO {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String formatKey(String key) {
|
private static String formatKey(String key) {
|
||||||
return String.format(IDEMPOTENT.getKeyTemplate(), key);
|
return String.format(IDEMPOTENT, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,13 @@
|
||||||
package cn.iocoder.yudao.framework.lock4j.config;
|
package cn.iocoder.yudao.framework.lock4j.config;
|
||||||
|
|
||||||
import cn.hutool.core.util.ClassUtil;
|
|
||||||
import com.baomidou.lock.spring.boot.autoconfigure.LockAutoConfiguration;
|
|
||||||
import cn.iocoder.yudao.framework.lock4j.core.DefaultLockFailureStrategy;
|
import cn.iocoder.yudao.framework.lock4j.core.DefaultLockFailureStrategy;
|
||||||
import cn.iocoder.yudao.framework.lock4j.core.Lock4jRedisKeyConstants;
|
import com.baomidou.lock.spring.boot.autoconfigure.LockAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
||||||
@AutoConfiguration(before = LockAutoConfiguration.class)
|
@AutoConfiguration(before = LockAutoConfiguration.class)
|
||||||
public class YudaoLock4jConfiguration {
|
public class YudaoLock4jConfiguration {
|
||||||
|
|
||||||
static {
|
|
||||||
// 手动加载 Lock4jRedisKeyConstants 类,因为它不会被使用到
|
|
||||||
// 如果不加载,会导致 Redis 监控,看到它的 Redis Key 枚举
|
|
||||||
ClassUtil.loadClass(Lock4jRedisKeyConstants.class.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public DefaultLockFailureStrategy lockFailureStrategy() {
|
public DefaultLockFailureStrategy lockFailureStrategy() {
|
||||||
return new DefaultLockFailureStrategy();
|
return new DefaultLockFailureStrategy();
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
package cn.iocoder.yudao.framework.lock4j.core;
|
package cn.iocoder.yudao.framework.lock4j.core;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
|
|
||||||
import org.redisson.api.RLock;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.HASH;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lock4j Redis Key 枚举类
|
* Lock4j Redis Key 枚举类
|
||||||
*
|
*
|
||||||
|
@ -12,8 +7,13 @@ import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.H
|
||||||
*/
|
*/
|
||||||
public interface Lock4jRedisKeyConstants {
|
public interface Lock4jRedisKeyConstants {
|
||||||
|
|
||||||
RedisKeyDefine LOCK4J = new RedisKeyDefine("分布式锁",
|
/**
|
||||||
"lock4j:%s", // 参数来自 DefaultLockKeyBuilder 类
|
* 分布式锁
|
||||||
HASH, RLock.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC); // Redisson 的 Lock 锁,使用 Hash 数据结构
|
*
|
||||||
|
* KEY 格式:lock4j:%s // 参数来自 DefaultLockKeyBuilder 类
|
||||||
|
* VALUE 数据格式:HASH // RLock.class:Redisson 的 Lock 锁,使用 Hash 数据结构
|
||||||
|
* 过期时间:不固定
|
||||||
|
*/
|
||||||
|
String LOCK4J = "lock4j:%s";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,113 +0,0 @@
|
||||||
package cn.iocoder.yudao.framework.redis.core;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonValue;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Redis Key 定义类
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class RedisKeyDefine {
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum KeyTypeEnum {
|
|
||||||
|
|
||||||
STRING("String"),
|
|
||||||
LIST("List"),
|
|
||||||
HASH("Hash"),
|
|
||||||
SET("Set"),
|
|
||||||
ZSET("Sorted Set"),
|
|
||||||
STREAM("Stream"),
|
|
||||||
PUBSUB("Pub/Sub");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 类型
|
|
||||||
*/
|
|
||||||
@JsonValue
|
|
||||||
private final String type;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum TimeoutTypeEnum {
|
|
||||||
|
|
||||||
FOREVER(1), // 永不超时
|
|
||||||
DYNAMIC(2), // 动态超时
|
|
||||||
FIXED(3); // 固定超时
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 类型
|
|
||||||
*/
|
|
||||||
@JsonValue
|
|
||||||
private final Integer type;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Key 模板
|
|
||||||
*/
|
|
||||||
private final String keyTemplate;
|
|
||||||
/**
|
|
||||||
* Key 类型的枚举
|
|
||||||
*/
|
|
||||||
private final KeyTypeEnum keyType;
|
|
||||||
/**
|
|
||||||
* Value 类型
|
|
||||||
*
|
|
||||||
* 如果是使用分布式锁,设置为 {@link java.util.concurrent.locks.Lock} 类型
|
|
||||||
*/
|
|
||||||
private final Class<?> valueType;
|
|
||||||
/**
|
|
||||||
* 超时类型
|
|
||||||
*/
|
|
||||||
private final TimeoutTypeEnum timeoutType;
|
|
||||||
/**
|
|
||||||
* 过期时间
|
|
||||||
*/
|
|
||||||
private final Duration timeout;
|
|
||||||
/**
|
|
||||||
* 备注
|
|
||||||
*/
|
|
||||||
private final String memo;
|
|
||||||
|
|
||||||
private RedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType,
|
|
||||||
TimeoutTypeEnum timeoutType, Duration timeout) {
|
|
||||||
this.memo = memo;
|
|
||||||
this.keyTemplate = keyTemplate;
|
|
||||||
this.keyType = keyType;
|
|
||||||
this.valueType = valueType;
|
|
||||||
this.timeout = timeout;
|
|
||||||
this.timeoutType = timeoutType;
|
|
||||||
// 添加注册表
|
|
||||||
RedisKeyRegistry.add(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType, Duration timeout) {
|
|
||||||
this(memo, keyTemplate, keyType, valueType, TimeoutTypeEnum.FIXED, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType, TimeoutTypeEnum timeoutType) {
|
|
||||||
this(memo, keyTemplate, keyType, valueType, timeoutType, Duration.ZERO);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 格式化 Key
|
|
||||||
*
|
|
||||||
* 注意,内部采用 {@link String#format(String, Object...)} 实现
|
|
||||||
*
|
|
||||||
* @param args 格式化的参数
|
|
||||||
* @return Key
|
|
||||||
*/
|
|
||||||
public String formatKey(Object... args) {
|
|
||||||
return String.format(keyTemplate, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package cn.iocoder.yudao.framework.redis.core;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link RedisKeyDefine} 注册表
|
|
||||||
*/
|
|
||||||
public class RedisKeyRegistry {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Redis RedisKeyDefine 数组
|
|
||||||
*/
|
|
||||||
private static final List<RedisKeyDefine> DEFINES = new ArrayList<>();
|
|
||||||
|
|
||||||
public static void add(RedisKeyDefine define) {
|
|
||||||
DEFINES.add(define);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<RedisKeyDefine> list() {
|
|
||||||
return DEFINES;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int size() {
|
|
||||||
return DEFINES.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -2,8 +2,3 @@
|
||||||
GET {{baseUrl}}/infra/redis/get-monitor-info
|
GET {{baseUrl}}/infra/redis/get-monitor-info
|
||||||
Authorization: Bearer {{token}}
|
Authorization: Bearer {{token}}
|
||||||
tenant-id: {{adminTenentId}}
|
tenant-id: {{adminTenentId}}
|
||||||
|
|
||||||
### 请求 /infra/redis/get-key-list 接口 => 成功
|
|
||||||
GET {{baseUrl}}/infra/redis/get-key-list
|
|
||||||
Authorization: Bearer {{token}}
|
|
||||||
tenant-id: {{adminTenentId}}
|
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.redis.vo;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
|
|
||||||
@Schema(description = "管理后台 - Redis Key 信息 Response VO")
|
|
||||||
@Data
|
|
||||||
@Builder
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class RedisKeyDefineRespVO {
|
|
||||||
|
|
||||||
@Schema(description = "Key 模板", requiredMode = Schema.RequiredMode.REQUIRED, example = "login_user:%s")
|
|
||||||
private String keyTemplate;
|
|
||||||
|
|
||||||
@Schema(description = "Key 类型的枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "String")
|
|
||||||
private RedisKeyDefine.KeyTypeEnum keyType;
|
|
||||||
|
|
||||||
@Schema(description = "Value 类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "java.lang.String")
|
|
||||||
private Class<?> valueType;
|
|
||||||
|
|
||||||
@Schema(description = "超时类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
|
||||||
private RedisKeyDefine.TimeoutTypeEnum timeoutType;
|
|
||||||
|
|
||||||
@Schema(description = "过期时间,单位:毫秒", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
|
||||||
private Duration timeout;
|
|
||||||
|
|
||||||
@Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "啦啦啦啦~")
|
|
||||||
private String memo;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.redis.vo;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
|
|
||||||
@Schema(description = "管理后台 - Redis Key 信息 Response VO")
|
|
||||||
@Data
|
|
||||||
@Builder
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class RedisKeyRespVO {
|
|
||||||
|
|
||||||
@Schema(description = "login_user:%s", requiredMode = Schema.RequiredMode.REQUIRED, example = "String")
|
|
||||||
private String keyTemplate;
|
|
||||||
|
|
||||||
@Schema(description = "Key 类型的枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "String")
|
|
||||||
private RedisKeyDefine.KeyTypeEnum keyType;
|
|
||||||
|
|
||||||
@Schema(description = "Value 类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "java.lang.String")
|
|
||||||
private Class<?> valueType;
|
|
||||||
|
|
||||||
@Schema(description = "超时类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
|
||||||
private RedisKeyDefine.TimeoutTypeEnum timeoutType;
|
|
||||||
|
|
||||||
@Schema(description = "过期时间,单位:毫秒", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
|
||||||
private Duration timeout;
|
|
||||||
|
|
||||||
@Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "啦啦啦啦~")
|
|
||||||
private String memo;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.infra.controller.admin.redis.vo;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Schema(description = "管理后台 - 单个 Redis Key Value Response VO")
|
|
||||||
@Data
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class RedisKeyValueRespVO {
|
|
||||||
|
|
||||||
@Schema(description = "c5f6990767804a928f4bb96ca249febf", requiredMode = Schema.RequiredMode.REQUIRED, example = "String")
|
|
||||||
private String key;
|
|
||||||
|
|
||||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, example = "String")
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,14 +1,11 @@
|
||||||
package cn.iocoder.yudao.module.infra.convert.redis;
|
package cn.iocoder.yudao.module.infra.convert.redis;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisKeyDefineRespVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisMonitorRespVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisMonitorRespVO;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
|
@ -29,6 +26,4 @@ public interface RedisConvert {
|
||||||
return respVO;
|
return respVO;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<RedisKeyDefineRespVO> convertList(List<RedisKeyDefine> list);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
package cn.iocoder.yudao.module.pay.dal.redis;
|
package cn.iocoder.yudao.module.pay.dal.redis;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
|
|
||||||
import org.redisson.api.RLock;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付 Redis Key 枚举类
|
* 支付 Redis Key 枚举类
|
||||||
*
|
*
|
||||||
|
@ -10,9 +7,14 @@ import org.redisson.api.RLock;
|
||||||
*/
|
*/
|
||||||
public interface RedisKeyConstants {
|
public interface RedisKeyConstants {
|
||||||
|
|
||||||
RedisKeyDefine PAY_NOTIFY_LOCK = new RedisKeyDefine("通知任务的分布式锁",
|
/**
|
||||||
"pay_notify:lock:%d", // 参数来自 DefaultLockKeyBuilder 类
|
* 通知任务的分布式锁
|
||||||
RedisKeyDefine.KeyTypeEnum.HASH, RLock.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC); // Redisson 的 Lock 锁,使用 Hash 数据结构
|
*
|
||||||
|
* KEY 格式:pay_notify:lock:%d // 参数来自 DefaultLockKeyBuilder 类
|
||||||
|
* VALUE 数据格式:HASH // RLock.class:Redisson 的 Lock 锁,使用 Hash 数据结构
|
||||||
|
* 过期时间:不固定
|
||||||
|
*/
|
||||||
|
String PAY_NOTIFY_LOCK = "pay_notify:lock:%d";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付序号的缓存
|
* 支付序号的缓存
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class PayNotifyLockRedisDAO {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String formatKey(Long id) {
|
private static String formatKey(Long id) {
|
||||||
return String.format(PAY_NOTIFY_LOCK.getKeyTemplate(), id);
|
return String.format(PAY_NOTIFY_LOCK, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue