feat(cache): 配置属性 redis-cache.*(TTL/抖动/滑动/击穿锁)
This commit is contained in:
48
src/main/java/com/njcn/middle/cache/autoconfig/RedisCacheProperties.java
vendored
Normal file
48
src/main/java/com/njcn/middle/cache/autoconfig/RedisCacheProperties.java
vendored
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package com.njcn.middle.cache.autoconfig;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis 缓存配置属性,前缀 {@code redis-cache}。全部可选,有合理默认。
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ConfigurationProperties("redis-cache")
|
||||||
|
public class RedisCacheProperties {
|
||||||
|
|
||||||
|
/** 统一 key 前缀。 */
|
||||||
|
private String keyPrefix = "cache:";
|
||||||
|
|
||||||
|
/** 是否按环境隔离 key。 */
|
||||||
|
private boolean envIsolation = false;
|
||||||
|
|
||||||
|
/** 环境标识(隔离开启且非空时拼入 key)。 */
|
||||||
|
private String env = "";
|
||||||
|
|
||||||
|
/** set/getOrLoad 不传 TTL 时的默认过期(秒)。 */
|
||||||
|
private long defaultTtlSeconds = 3600;
|
||||||
|
|
||||||
|
/** 空值标记 TTL(秒)——穿透防护,宜短。 */
|
||||||
|
private long nullTtlSeconds = 60;
|
||||||
|
|
||||||
|
/** TTL 随机抖动比例——雪崩防护;0 关闭抖动。 */
|
||||||
|
private double jitterRatio = 0.1;
|
||||||
|
|
||||||
|
/** 读命中真实值时自动续期(滑动过期),默认关闭。 */
|
||||||
|
private boolean slidingExpireEnabled = false;
|
||||||
|
|
||||||
|
private Breakdown breakdown = new Breakdown();
|
||||||
|
|
||||||
|
/** 击穿:互斥锁。 */
|
||||||
|
@Data
|
||||||
|
public static class Breakdown {
|
||||||
|
/** 关闭后 getOrLoad 退化为无锁直接回源。 */
|
||||||
|
private boolean enabled = true;
|
||||||
|
/** 锁持有 TTL(ms),防持锁线程崩溃死锁。 */
|
||||||
|
private long lockTtlMs = 10000;
|
||||||
|
/** 未抢到锁的线程最长等待(ms),超时降级直接回源。 */
|
||||||
|
private long waitTimeoutMs = 3000;
|
||||||
|
/** 未抢到锁时自旋重读间隔(ms)。 */
|
||||||
|
private long waitIntervalMs = 50;
|
||||||
|
}
|
||||||
|
}
|
||||||
44
src/test/java/com/njcn/middle/cache/autoconfig/RedisCachePropertiesTest.java
vendored
Normal file
44
src/test/java/com/njcn/middle/cache/autoconfig/RedisCachePropertiesTest.java
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package com.njcn.middle.cache.autoconfig;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.context.properties.bind.Binder;
|
||||||
|
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
|
||||||
|
import org.springframework.mock.env.MockEnvironment;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
class RedisCachePropertiesTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void defaults() {
|
||||||
|
RedisCacheProperties p = new RedisCacheProperties();
|
||||||
|
assertEquals("cache:", p.getKeyPrefix());
|
||||||
|
assertFalse(p.isEnvIsolation());
|
||||||
|
assertEquals("", p.getEnv());
|
||||||
|
assertEquals(3600, p.getDefaultTtlSeconds());
|
||||||
|
assertEquals(60, p.getNullTtlSeconds());
|
||||||
|
assertEquals(0.1, p.getJitterRatio());
|
||||||
|
assertFalse(p.isSlidingExpireEnabled());
|
||||||
|
assertTrue(p.getBreakdown().isEnabled());
|
||||||
|
assertEquals(10000, p.getBreakdown().getLockTtlMs());
|
||||||
|
assertEquals(3000, p.getBreakdown().getWaitTimeoutMs());
|
||||||
|
assertEquals(50, p.getBreakdown().getWaitIntervalMs());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void relaxedBinding() {
|
||||||
|
MockEnvironment env = new MockEnvironment()
|
||||||
|
.withProperty("redis-cache.default-ttl-seconds", "1800")
|
||||||
|
.withProperty("redis-cache.sliding-expire-enabled", "true")
|
||||||
|
.withProperty("redis-cache.breakdown.lock-ttl-ms", "5000")
|
||||||
|
.withProperty("redis-cache.breakdown.enabled", "false");
|
||||||
|
RedisCacheProperties p = Binder.get(env)
|
||||||
|
.bind("redis-cache", RedisCacheProperties.class).get();
|
||||||
|
assertEquals(1800, p.getDefaultTtlSeconds());
|
||||||
|
assertTrue(p.isSlidingExpireEnabled());
|
||||||
|
assertEquals(5000, p.getBreakdown().getLockTtlMs());
|
||||||
|
assertFalse(p.getBreakdown().isEnabled());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user