feat(cache): 缓存常量与 key 构造器(前缀 + 环境隔离 + 锁 key 派生)
This commit is contained in:
19
src/main/java/com/njcn/middle/cache/constant/CacheConstant.java
vendored
Normal file
19
src/main/java/com/njcn/middle/cache/constant/CacheConstant.java
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
package com.njcn.middle.cache.constant;
|
||||
|
||||
/**
|
||||
* Redis 缓存相关常量。
|
||||
*/
|
||||
public final class CacheConstant {
|
||||
|
||||
private CacheConstant() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 空值标记:回源结果为 null 时写入此值(穿透防护)。
|
||||
* 内含 NUL 控制字符(Java unicode 转义书写),fastjson 序列化任何对象都不会产出含 NUL 的裸文本,故无冲突。
|
||||
*/
|
||||
public static final String NULL_SENTINEL = "\u0000NULL\u0000";
|
||||
|
||||
/** 击穿互斥锁 key 后缀(由数据 key 派生)。 */
|
||||
public static final String LOCK_SUFFIX = ":__lock__";
|
||||
}
|
||||
36
src/main/java/com/njcn/middle/cache/support/CacheKeyBuilder.java
vendored
Normal file
36
src/main/java/com/njcn/middle/cache/support/CacheKeyBuilder.java
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
package com.njcn.middle.cache.support;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.njcn.middle.cache.constant.CacheConstant;
|
||||
|
||||
/**
|
||||
* 缓存 key 构造器:统一前缀 +(可选)环境隔离段。
|
||||
*
|
||||
* <p>基础:{@code keyPrefix + bizKey};开启隔离且 env 非空:{@code keyPrefix + env + ":" + bizKey}。
|
||||
* 锁 key 由数据 key 派生,保证数据与其锁落在同一隔离域。
|
||||
*/
|
||||
public class CacheKeyBuilder {
|
||||
|
||||
private final String keyPrefix;
|
||||
private final boolean envIsolation;
|
||||
private final String env;
|
||||
|
||||
public CacheKeyBuilder(String keyPrefix, boolean envIsolation, String env) {
|
||||
this.keyPrefix = keyPrefix == null ? "" : keyPrefix;
|
||||
this.envIsolation = envIsolation;
|
||||
this.env = env;
|
||||
}
|
||||
|
||||
/** 业务 key → 实际数据 key。 */
|
||||
public String build(String bizKey) {
|
||||
if (envIsolation && StrUtil.isNotBlank(env)) {
|
||||
return keyPrefix + env + ":" + bizKey;
|
||||
}
|
||||
return keyPrefix + bizKey;
|
||||
}
|
||||
|
||||
/** 数据 key 派生锁 key。 */
|
||||
public String buildLock(String bizKey) {
|
||||
return build(bizKey) + CacheConstant.LOCK_SUFFIX;
|
||||
}
|
||||
}
|
||||
34
src/test/java/com/njcn/middle/cache/support/CacheKeyBuilderTest.java
vendored
Normal file
34
src/test/java/com/njcn/middle/cache/support/CacheKeyBuilderTest.java
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
package com.njcn.middle.cache.support;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class CacheKeyBuilderTest {
|
||||
|
||||
@Test
|
||||
void buildWithPrefixOnly() {
|
||||
CacheKeyBuilder kb = new CacheKeyBuilder("cache:", false, "");
|
||||
assertEquals("cache:user:1", kb.build("user:1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildWithEnvIsolation() {
|
||||
CacheKeyBuilder kb = new CacheKeyBuilder("cache:", true, "prod");
|
||||
assertEquals("cache:prod:user:1", kb.build("user:1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void envIsolationButBlankEnvFallsBack() {
|
||||
CacheKeyBuilder kb = new CacheKeyBuilder("cache:", true, "");
|
||||
assertEquals("cache:user:1", kb.build("user:1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildLockDerivesFromDataKey() {
|
||||
assertEquals("cache:user:1:__lock__",
|
||||
new CacheKeyBuilder("cache:", false, "").buildLock("user:1"));
|
||||
assertEquals("cache:prod:user:1:__lock__",
|
||||
new CacheKeyBuilder("cache:", true, "prod").buildLock("user:1"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user