现场是这样的。日志里蜘蛛请求都带 If-Modified-Since,源站却全部返回 200 和完整 HTML,带宽占用高,抓取统计里单页下载大小一直在涨。
中间走过弯路,把「Nginx 的 fastcgi_cache 没开,条件请求到不了缓存层」当成主因,改完现象没变。
排查方向其实有限,先把可能性排一排。动态页面由 PHP 输出,没有比对请求头里的时间;Last-Modified 每次渲染都变,条件请求必然不命中;响应里没有 ETag,蜘蛛只能靠时间判断。
先看请求头和响应头
curl -sI -H 'If-Modified-Since: Wed, 05 Nov 2026 02:00:00 GMT' https://www.example.com/post/1 | head -8
再往下确认 Last-Modified 是否稳定
curl -sI https://www.example.com/post/1 | grep -i last-modified
然后在应用层补 304 判断
if (strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $modified) { http_response_code(304); exit; }
等前面都确认过,再统计 200 与 304 的比例
awk '{print $9}' access.log | sort | uniq -c | sort -rn | head -5
手上没有现成的复现脚本,就照着线上请求手工拼了一个。
怎么算真的好了,看的是同一批现象。重复请求返回 304,日志里 200 的下载量下降,抓取统计中的平均下载大小回落到正常区间。
条件请求要生效,Last-Modified 必须对应内容本身,用渲染时间当修改时间等于每次都告诉蜘蛛页面变了。这类问题最好一次改到位,反复小改反而容易把原因搅混。
