现场是这样的。站内搜索地址是 /?s=关键词,CDN 的缓存键只取路径不取参数,第一个人搜的词被缓存后,后面所有人看到的都是同一批结果。用户投诉搜索结果不对,蜘蛛抓到的也是错内容。

中间走过弯路,把「CDN 默认忽略营销参数,把 s 也当成无关参数」当成主因,改完现象没变。

原因不止一个,得分开看。缓存键没有包含 query string,所有搜索词共用一份缓存;搜索页响应头没写 Cache-Control private 或 no-store;命中缓存后源站日志没有记录,排查时看不到真实请求。

先用两个词验证是否串号

curl -s 'https://www.example.com/?s=nginx' | md5sum; curl -s 'https://www.example.com/?s=mysql' | md5sum

接着看响应头的缓存状态

curl -sI 'https://www.example.com/?s=nginx' | grep -i 'x-cache\|cache-control'

再往下把搜索页设为不缓存

add_header Cache-Control 'no-store, private' always;

调整缓存键包含参数

curl -X PURGE 'https://www.example.com/?s=nginx'

恢复的判定其实很直接。两个不同搜索词返回的内容不再相同,响应头显示 bypass,缓存命中率略降但搜索功能恢复正常。

这里还有个坑。动态查询页默认就不该进共享缓存,省下的那点回源流量,换来的是用户和蜘蛛都拿到错页面。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189