产线MES过站慢?一次“缓存穿透”引发的600ms案例

发布时间:2026/9/28 18:40:50
产线MES过站慢?一次“缓存穿透”引发的600ms案例
引言在 .NET 性能排障系列中我们聊过内存暴涨也聊过 CPU 飙高。但有一种问题它不挑内存不挑 CPU专挑核心业务链路下手。今天这个故事从产线工人的一句“过站慢”开始最终定位到一个经典的缓存穿透坑。一、现象产线卡顿接口耗时 3s业务反馈产线 MES 过站如MoveInByHand接口明显变慢工人扫码后要卡顿好几秒才能继续。查监控核心接口MoveInByHand的upstream_time后端处理时长频繁超过3.6 秒确实慢得离谱。二、追踪TraceId 暴露“字典”瓶颈慢在哪里拿出其中一个慢请求的traceId展开链路真相初现请求中获取数据字典缓存 Redis --》 请求公共域系统管理服务居然花了将近2 秒多排查几个请求发现共同特点凡是慢的都卡在这个“数据字典”上。进一步查所有索取数据字典的接口日志发现大量请求~10个/S同时请求同一个数据字典编码如 XXX_PROC_XMT_XIAO_VALIDATE_WORK_OPERATION单次接口耗时约600ms并发叠加后直接拖垮过站主链路。三、根因一个开关引发缓存穿透看代码过站逻辑新加了一个数据字典配置开关。致命点在这里现场没有配置这个数据字典。代码逻辑先查缓存Redis/本地缓存没命中则查系统管理服务。未配置 缓存永远不命中。由于“没有配置数据字典”这个否定结果没有被写入缓存代码中if (item null)直接返回未做空值缓存导致每次过站请求都穿透缓存直击系统管理服务。结论高并发过站 未配置字典 空值不缓存 缓存穿透​ → 系统管理服务被高频击穿600ms×N → 主接口耗时 3s → 产线卡顿。四、修复防御性缓存设计止血方案空值缓存核心对于“未配置”的数据字典缓存一个短时效的空值如null或特定标记TTL 30s~1min避免重复穿透。降级开关若字典未配置直接走默认逻辑不过站校验不发起远程调用。改动示意伪代码var item _cacheManager.GetCacheDictItem(cacheName); if (item null) { // 原逻辑直接返回导致穿透 // 修复查系统服务 item await _sysService.GetDictAsync(code); // 修复无论是否空都写短缓存 _cacheManager.Set(cacheName, item ?? NULL_MARK, TimeSpan.FromSeconds(30)); }发布后数据字典请求骤降过站接口回归毫秒级产线恢复丝滑。五、复盘缓存穿透防御清单陷阱表现防御缓存穿透​查询不存在的 key直击 DB/远程服务①空值缓存短TTL ②布隆过滤器 ③接口校验缓存雪崩​大量 key 同时失效随机 TTL 偏移缓存击穿​热点 key 失效瞬间高并发互斥锁/永不过期一句话总结“没配置”不是免死金牌反而可能是穿透的元凶。缓存设计必须考虑否定场景——空值也要有归宿否则每一次过站都是对下游的一次“DDoS”。