缓存有效期配置不支持小数且单位必须严格为ms/s/m/h/d全小写,否则静默失效;如3.5s、5m、5min均非法,正确写法为3500ms或300s,并需通过启动日志或caffeinespec.parse()验证生效。

缓存有效期设置不支持小数或单位写错,是配置阶段最常踩的“低级但致命”坑。它不会报错,也不会抛异常,而是让缓存行为完全失控——比如本该5秒过期,结果变成5毫秒、5小时甚至永不过期。
看配置格式是否符合规范
Caffeine、Redis、Spring Cache 等主流缓存组件对 spec 或 ttl 字符串格式有严格要求,不接受小数,也不容忍单位拼写错误:
-
不支持小数:像
expireAfterAccess=3.5s是非法的,会静默忽略该参数,退化为无过期策略;必须写成整数,如3s、3500ms、210s -
单位必须全小写且准确:只认
ms、s、m、h、d(注意不是sec、min、hr);expireAfterAccess=5M(大写 M)会被当作非法单位丢弃 -
空格和等号不能多也不能少:
"maximumSize=500 , expireAfterAccess=60s"中逗号后带空格,部分旧版 Spring Boot 会解析失败;推荐不加空格:"maximumSize=500,expireAfterAccess=60s"
验证配置是否真正生效
光看配置文件没用,得确认运行时实际加载的值:
- 启动日志里搜索
CaffeineCacheManager或Cache specification,Spring Boot 通常会打印最终解析后的 spec 字符串,比如:Using cache spec: maximumSize=500,expireAfterAccess=60000ms - 在代码中注入
CacheManager,调用getCache("org-data")获取缓存实例,再通过反射或调试查看其内部expireAfterAccess字段值(Caffeine 的cache.policy().expireAfterAccess()可直接获取 Duration) - 写个简单测试:put 一个 key,sleep 小于/大于设定时间,再 get —— 如果始终能取到,说明过期未启用;如果立刻取不到,可能是单位误写成 ms 导致过期太快
单位混淆的典型错误对照
这些写法看着像,实际效果天差地别:
-
expireAfterAccess=300→ 默认单位是纳秒(不是秒!),几乎等于立即过期 -
expireAfterAccess=300s→ 正确,300 秒 -
expireAfterAccess=5m→ 正确,5 分钟;5min或5mins→ 无效 -
expireAfterAccess=1h→ 正确;1hr、1hour→ 不识别,整个 spec 可能被跳过
配置建议与兜底习惯
避免靠记忆写单位,用明确、防错的方式固化习惯:
- 统一用毫秒或秒,避免混用;例如全部写成
60000ms或60s,不写1m - 在 YAML 配置里加注释说明单位:
# 单位:毫秒,整数,不可写小数 - 上线前必做一项检查:把配置项复制进单元测试,用
CaffeineSpec.parse()主动解析,捕获IllegalArgumentException异常 - 关键业务缓存,加上监控埋点:记录每次 get 时距上次 access 的耗时,对比预期 TTL,异常波动即告警











