问题出现得很突然,日志倒是留得挺全。详情页的响应头里带着 Set-Cookie: PHPSESSID=...,CDN 照样把整页缓存了。蜘蛛每次抓到的 session id 都不同,日志里同一篇文章出现几十次不同 cookie 的请求记录,抓取量统计虚高,缓存命中率却只有 12%。
刚开始盯着「应用在 GET 请求里就下发会话,其实只有登录后才需要」,折腾了半个多小时,排掉了。
真正麻烦的地方在于,几个原因的现象几乎一样。响应头没有 private 或 no-store,边缘按公开内容缓存。另一种情况是Vary 里没有 Cookie,边缘无法按会话区分。
另外,缓存键带上了 cookie 变体,同一个页面被拆成很多份。
第一件事是看响应头里是否带 Set-Cookie 以及缓存策略
curl -sI https://www.example.com/p/1024 | grep -i -E 'set-cookie|cache-control|vary'
给匿名访问的页面去掉会话下发
session_start() 只在 POST 或登录态调用
公开页面明确声明可共享缓存,并去掉 cookie 维度
Cache-Control: public, s-maxage=600
末了清掉带 cookie 的缓存变体后看命中率
curl -sI https://www.example.com/p/1024 | grep -i x-cache
改完先别撤,确认这几项。匿名请求不再返回 Set-Cookie,缓存命中率升到八成以上,日志里同一篇文章的重复请求消失。
补一句。把 cookie 加进 Vary 会让缓存命中率直接归零,正确的做法是根本不在这类响应里发 cookie。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。
