做站点运营时,大家更愿意花时间在栏目规划和内容更新上,而服务器时间、时区、缓存校验头这些配置,往往在搭建初期随手设好就再没回看过。它们平时很安静,一旦出问题却很隐蔽:蜘蛛拿到的 Last-Modified 比真实更新时间还新,或者多台机器时间不一致,缓存判定就会乱掉。
先看服务器时间本身
时间戳几乎贯穿抓取链路的每个环节:响应头里的 Date、Last-Modified、Expires,日志里的访问时刻,定时任务的执行时间,都来自系统时钟。时间不准,后面的判断都建立在错误前提上。
- 校时:确认服务器已配置 NTP,并检查同步是否长期失败。手工改过时间的机器,尤其容易在中途慢慢漂移。
- 时区:应用层建议统一用 UTC 记录,展示层再按需转换。多台机器时区不一致时,日志拼在一起会出现“访问时间倒流”。
- 多节点一致性:负载均衡后的多台后端,时间差最好控制在秒级以内,否则同一份缓存会出现不同的新鲜度判断。
- 与外部系统对齐:数据库、缓存服务、对象存储的时间如果相差过大,签名校验和过期策略都可能失败。
再看缓存校验头
Last-Modified
Last-Modified 应该反映内容最后一次实质变更的时间。常见问题是:每次渲染都取当前时间,导致页面看起来“永远刚更新过”,蜘蛛每次都重新拉全文;或者模板改动时顺手改写了时间,让没变的内容显得变了。
ETag
ETag 是内容的指纹,理想情况下内容不变时它应保持不变。如果它由进程号、随机数或带时间的字符串生成,每次请求都会变,条件请求就失去意义,304 也就无从谈起。
验证 304 是否真的生效
- 用 curl 带上 If-Modified-Since 请求一个稳定页面,观察是否返回 304。
- 带上 If-None-Match 复用上一次拿到的 ETag,确认同样返回 304。
- 连续请求两次,比较 ETag 是否一致。若每次都不同,说明生成方式需要调整。
- 检查 Expires、Cache-Control 的过期时间是否与页面类型匹配。
- 修改页面中的一小段正文,确认 Last-Modified 更新、ETag 改变、返回 200。
日志时间线也要对齐
分析抓取频次、响应时间时,日志时间是基础坐标。如果服务器用本地时区写日志,分析脚本却按 UTC 解读,就会出现固定偏移,把白天和夜间的抓取分布看反。
时间相关问题很少单独出现,通常表现为抓取量忽多忽少、缓存命中率异常、日志里的访问顺序对不上。排查时先确认时间基准,再往上层找原因。
一份简短的自查清单
- NTP 同步正常,多节点时间差在秒级以内。
- 日志、响应头、定时任务的时区口径一致,并记录在文档中。
- Last-Modified 只在内容实质变更时更新。
- ETag 稳定可复现,不包含随机或易变元素。
- 304 与缓存过期策略符合页面类型:静态资源可以长缓存,正文页保持适度。
- 发布系统与服务器时间对齐,避免定时发布提前或延后。
这些项目都不复杂,但需要在改动上线后定期回看。把时间基准和缓存校验理顺,后面的栏目规划、内容更新和抓取分析才有一个可靠的参照。