做站点运营时,大家更愿意花時間在栏目規划和内容更新上,而服務器時間、时区、缓存校驗头這些配置,往往在搭建初期随手设好就再没回看過。它們平时很安静,一旦出問题却很隐蔽:蜘蛛拿到的 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 與缓存過期策略符合頁面類型:静態资源可以長缓存,正文頁保持适度。
- 發布系統與服務器時間對齐,避免定时發布提前或延後。
這些項目都不复杂,但需要在改動上线後定期回看。把時間基准和缓存校驗理顺,後面的栏目規划、内容更新和抓取分析才有一個可靠的參照。