后台配置页里那个"保存成功"的假象:我是怎么被缓存耍了三次的

小助手
小助手 版主圣羽星庭 勋望元宿志愿先锋
社区管理
站长杂谈 106 浏览 0 回复

上周给后台加了一套 SMTP 发信配置,表单提交、入库、弹窗提示"保存成功"一气呵成。结果测试发邮件时愣是走的旧服务器地址,排查半小时才发现——配置确实写进数据库了,但读取走的是 Redis 缓存,而我忘了在 save 之后刷 key。

这已经不是第一次了。第一次是阿里云 OSS 的 endpoint 切到内网域名,后台改完以为万事大吉,前端上传报错 "InvalidEndpoint" 才想起缓存没清。第二次更离谱,CDN 的 HTTPS 强制跳转开关,配置页显示已开启,实际回源还是走 80 端口,查日志查到半夜,最后拍脑袋:哦,缓存 TTL 设了 3600 秒。

现在我给配置模块定了三条铁律,分享出来看看有没有同道中人:

一、读写必须同一路径,别搞"双轨制"

以前图省事,写配置用 `ConfigModel::update()`,读配置却从 `cache('site_config')` 拿。结果就是库和缓存各说各话。现在强制走同一个 Service 方法:`ConfigService::get($key)` 和 `ConfigService::set($key, $value)`,set 里必须包一层 `Cache::tag('config')->clear()`,get 先读缓存、缓存 miss 再回库,回库后顺便把缓存补上。宁可多一次查询,也别让两边分叉。

二、表单保存后给用户真反馈,别只弹"成功"

之前保存完就一句 toast,用户(包括我自己)默认配置已生效。现在我在配置页加了行小字:"当前生效值:xxx",从缓存实时读回来展示。如果数据库值和缓存值不一致,按钮旁边飘个黄标提示"缓存待刷新"。虽然有点丑,但再也不用猜了。

三、批量配置用事务+延迟双删,别赌运气

有次做支付参数配置,商户号、密钥、回调地址三个字段一起改,保存时只刷了主键缓存,结果密钥走了新值、回调地址走了旧值,微信支付签名死活对不上。现在批量更新套事务,提交成功后先删缓存、再写库、最后异步队列二次删缓存(防并发读库写回旧值)。延迟双删那 500 毫秒用 Redis 队列丢出去,宁可慢半拍,也别阴阳配。

还有个骚操作:我在配置表加了 `last_modified` 字段,每次读取时比对缓存时间戳,如果库里的更新时间更新,自动视为缓存失效。相当于给缓存加了道"软过期"保险,不用硬等 TTL。

最讽刺的是,这些坑全是"保存成功"四个字 masking 掉的。后台配置页看似简单,真要做到"所见即所得",比写十个业务接口还费神。你们有没有被配置缓存背刺过?我目前三次,估计还会有第四次。

评论0
回复 · 0
还没有回复
微信客服 微信客服