← 洞见最新技术展示

改了价没生效,问题常在三层缓存

泛友数字2026/11/02 09:4677 阅读
改了价没生效,问题常在三层缓存

改完价格没生效,别急着重启服务。按 CDN、手机本地、接口缓存三层往下排,每层五分钟能排除。三层都干净还不对,问题在数据源,不在缓存。

仓库、门店、顾客手里各有一本价目表。仓库改了,门店那本没换,顾客翻到的还是上周那页。缓存就像这三本册子,改价要三本一起改。

先说清缓存是什么。系统为了快,把上次算好的结果先存一份,下次直接给。源头改了,副本要等过期,或者被人手动清掉,才会更新。

三层的位置不一样,责任人也不同。

哪一层存在哪谁负责清典型现象
CDN/边缘各地机房运维这个城市新、那个城市旧
手机本地微信或浏览器用户或前端同一人老看到旧价,换手机就新
接口缓存服务器内存或 Redis开发所有人都旧,数据库里却是新价

先看现象的范围,范围决定查哪层。所有人都是旧价,先查接口。个别手机旧,先查本地。分地区新旧不一,先查 CDN。

第一层,CDN 和边缘节点。

CDN 是内容分发网络,把图片、脚本、页面这些文件复制到各地机房,让用户就近取。价格如果写在前端页面或图片里,这层就可能是元凶。

最快的验证是换网络。手机关掉 Wi-Fi 用流量,或者反过来,再打开同一页。两边价格不一样,基本就是边缘节点没同步。

第二个办法是在网址后面加个随机参数,比如 ?v=20261102。参数一变,缓存认不出是同一份,只能回源取新的。新价出来了,说明源站没问题,是缓存旧。

确认是这层,去 CDN 控制台提交刷新。腾讯云的文档写明两种:刷新 URL 删除对应资源的缓存,刷新目录可以只刷变更过的部分。

刷新也有代价。文档里 URL 刷新每个账号单日一万条,目录刷新单日一百条,这是默认额度。价格页文件不多够用,别拿它当日常发布手段。

刷新成功后节点上没有有效缓存,用户再来会回源拉新的。大量刷新会让回源请求突增,源站要扛得住。

大促前还可以反过来做:预热。刷新是删掉节点上的旧文件,预热是把源站文件提前推到节点,用户第一次访问就能命中。

更稳的做法是给文件改名或加版本号。price.js 改成 price.v2.js,缓存自然失效,不用等刷新,也不用担心配额。

第二层,手机本地。

这层在用户手上。小程序用 wx.setStorage 把数据存在手机里,浏览器用 localStorage,HTTP 响应也可能被浏览器缓存住。

微信的文档给得明确:单个 key 最多 1MB,一个用户在一个小程序里总共 10MB。数据按用户隔离,A 用户读不到 B 用户的。

关键在清理时机。文档写的是,只有代码包被清理时,本地缓存才会被清理。用户不删小程序,你改的那份价目表可能一直躺在他手机里。

验证很快。微信里进「我 → 设置 → 通用 → 存储空间」,找到这个小程序清掉缓存,再进去看。价格变新,就是这层。

更彻底的办法是删掉小程序重新进。或者找一个从没打开过它的同事,用他的手机看。新手机新价、老手机旧价,答案很清楚。

这层最常见的坏习惯,是把整张价目表存本地,启动时先读本地再请求。网络一慢,用户看到的永远是上次的价。

改法不复杂。价格这种会变的数据,本地只当缓存用,存的时候带上时间。超过十分钟就先用旧值顶着,同时后台刷新。

第三层,服务端接口缓存。

这层在服务器上。一个接口要查几张表,开发就在前面加一层缓存,常见是 Redis 这类内存数据库,也有直接把结果放在程序内存里的。价格改了,缓存的键没清,接口继续返回旧值。

验证是加随机参数。在接口地址后加一个时间戳,缓存键变了,请求必定穿透到数据库。新价出来了,说明缓存没清干净。

还有一招更直接:让开发在数据库里查一次。数据库是新价、接口返回是旧价,中间那层缓存就跑不掉。

HTTP 缓存另有规则。RFC 9111 定义了缓存怎么存、怎么复用,响应头里的 Cache-Control 决定这份能不能存、存多久。

三个值要认得。max-age 是保质期,单位秒;no-store 是一律不存;must-revalidate 是过期后必须先问源站,不能拿旧的顶。

所以让开发查两处:接口返回头里有没有 Cache-Control,值是多少;缓存键里有没有带价格版本或更新时间。

换账号也能帮忙。价格如果按门店、按会员等级算,缓存键只写了商品编号,就会串价。A 门店的价被 B 门店看到,是键少了一个维度。

三层都排除了还不对,那就不是缓存。常见四种,一种比一种隐蔽。

  • 改错了表:前台一个价、后台一个价,中间还有一张渠道价。改价前先问清改哪张。
  • 快照价:购物车和订单存的是加购那一刻的价格,这是设计如此,不是没生效。
  • 多门店没同步:只改了一家,其他门店还是原价,后台也没提示。
  • 改在测试环境:页面地址看着一样,其实是另一套数据。

第一种最常见。很多系统有三套价格:展示价、会员价、结算价。改了一套,另外两套不动,页面当然没反应。

快照价也别急着当故障。订单按下单时的价结算,是会计要求,不是程序错了。要改的是规则,不是缓存。

还有一种「没生效」是时间没到。价格带生效时间,后台显示已保存,前台要等到点才换。这类先看生效时间字段,别去清缓存。

判断缓存旧不旧,看一个信号就够:同一份数据,换个入口看。后台是新价,小程序是旧价,中间一定有一层在挡。

排查顺序建议固定:先看范围,再排三层,最后查数据源。范围是所有人,先查接口;是个别人,先查手机;是分地区,先查 CDN。

改价流程加三步。后台确认新值,用一台没缓存过的设备下一单,再看接口的原始返回。三步都过,再通知客户。

技术上还有一件值得做的事:缓存键带版本号。价格表加一个更新时间,键里拼上它,价格一改键就变,旧缓存自然没人读。

这比每次手动清缓存可靠。手动清靠人记得,版本号靠代码保证。

最后一句话。缓存不是故障,是设计。要问的不是为什么有缓存,而是这份数据允许旧多久。价格允许旧五分钟,就设五分钟;一分钟都不许,就别缓存。

三层缓存排查顺序
三层各有各的验证:换网络、清本地、加随机参数。