- CacheController
java
@RestController
@RequestMapping("/api/cache")
@CrossOrigin
public class CacheController {
//final保证了不可变性
private final LocalCacheManage cacheManage;
//构造函数注入依赖
public CacheController(LocalCacheManage cacheManage) {
this.cacheManage = cacheManage;
}
/**
* 业务接口:前端通过接口模拟并发抢购
*/
@GetMapping("/get/{key}")
public Map<String,Object> getData(@PathVariable("key") String key){
long start=System.currentTimeMillis();
String result= cacheManage.get(key,()->{ //先找缓存,如果没有,则执行loader.call
TimeUnit.SECONDS.sleep(2);
return "Real_Database"+key;
});
long end=System.currentTimeMillis();
long duration=end-start;
Map<String,Object> response=new HashMap<>();
response.put("result",result);
response.put("duration",duration);
response.put("timestamp",System.currentTimeMillis());
return response;
}
/**
* 监控大屏接口:前端定时轮询获取最新命中率
*/
@GetMapping("/stats")
public Map<String, Object> getStats() {
return cacheManage.getMetrics();
}
/**
* 重置接口:一键清空重来
*/
@PostMapping("/clear")
public String clearCache() {
cacheManage.clear();
return "success";
}
}- LocalCacheManage
java
/**
* 核心并发组件:交由Spring容器单例管理
*/
@Component
public class LocalCacheManage {
//底层高并发共享容器,保证多人操作不乱套,本地内存
private final ConcurrentMap<String,String> cache=new ConcurrentHashMap<>();
//核心监控指标
private final AtomicInteger hitCount=new AtomicInteger(0);
private final AtomicInteger missCount=new AtomicInteger(0);
private final AtomicInteger blockedCount=new AtomicInteger(0); //记录被限流保护挡在外面的请求
//防击穿限流器:只允许一个线程查数据库
private final Semaphore backOriginSemaphore=new Semaphore(1);
/**
* 核心获取方法
*/
public String get(String key, Callable<String> loader) {
String value = cache.get(key);
if (value!= null) {
hitCount.incrementAndGet();
return value; // 极速命中
}
// 只有获取到信号量,才算真正的“回源(红色)”
if (backOriginSemaphore.tryAcquire()) {
try {
value = cache.get(key);
if (value != null) {
hitCount.incrementAndGet();
return value;
}
missCount.incrementAndGet(); // 真正穿透到数据库,记录 1 次红色
System.out.println(Thread.currentThread().getName()+"执行耗时慢查询...");
value = loader.call();
if (value != null) cache.put(key, value);
return value;
} catch (Exception e) {
return "异常";
} finally {
backOriginSemaphore.release();
}
} else {
// 没抢到信号量,算作“拦截保护(灰色)”
blockedCount.incrementAndGet();
return "系统繁忙";
}
}
/**
* 暴露给前端的监控数据
*/
public Map<String,Object> getMetrics(){
Map<String,Object> stats=new HashMap<>();
stats.put("hitCount",hitCount.get());
stats.put("missCount",missCount.get());
stats.put("blockedCount",blockedCount.get());
int total=hitCount.get()+missCount.get();
double hitRate = total==0?0:(double)hitCount.get()/total*100; //点击率
stats.put("hitRate", String.format("%.2f", hitRate)); // 保留两位小数
return stats;
}
/**
* 充值数据
*/
public void clear(){
cache.clear();
hitCount.set(0);
missCount.set(0);
blockedCount.set(0);
}
}测试: 
LocalCacheManage 是一个基于 JVM 本地内存构建的应用级高并发缓存组件。其在系统架构中的核心价值主要体现在:
- 响应性能: 提供微秒级的数据读取能力,消除网络 I/O 延迟。
- 高可用与容灾保障: 作为系统的“第一道防线”,在瞬时极高并发场景下,有效拦截绝大部分读请求,保护底层关系型数据库免受过载宕机风险。
- 缓存击穿防御:针对热点 Key 失效的瞬间,通过并发控制机制,保证回源操作的串行化或限流,彻底解决缓存击穿问题。