站点流量不大时,服務器對蜘蛛的抓取几乎無感。但当站内 URL 規模上去,或者某批頁面突然被重新抓取,日誌里就會出現集中的訪問:响應時間從几十毫秒涨到几秒,偶尔冒出 500、502,資料库连接也接近打满。這时候容易走两個极端——要么随手把 UA 封掉,要么什么都不做硬扛。两種做法都不太划算。
先確認這确實是蜘蛛
很多所谓的抓取高峰其實是采集程序或掃描器,UA 里寫着蜘蛛的名字。判断方法不复杂:看来源 IP 是否属于搜尋引擎公布的地址段,看請求的 URL 分布是否符合站内结构,看它有没有請求 robots.txt 和 Sitemap。如果大量請求集中在搜尋接口、登入頁、導出接口上,基本可以确定不是正经蜘蛛。
確認真實之後,再看它抓的是哪些頁面。多數情况下压力只来自少數几類:带參數的篩選頁、站内搜尋结果頁、按日期归档的列表頁。這些頁面數量大、内容重复、每次都要查询資料库,是拖慢响應的高频来源。
缓存通常比任何限制都有效
蜘蛛請求的是同一批 URL,且不带登入態、不带個性化 Cookie,是缓存最理想的受众。把公開頁面做成可缓存,命中率往往能上去一大截。
- 為公開頁面設定合理的 Cache-Control,区分浏览器缓存和 CDN 缓存的时長;
- 對動態生成的列表頁、詳情頁做整頁缓存或片段缓存,注意只對未登入訪客生效;
- 把图片、CSS、JS 交给缓存节点,避免每次抓取都回源;
- 检查缓存键里是否混進了多余參數,否則同一個頁面會生成大量缓存副本,等于没缓存。
缓存生效後再看服務器响應時間,多數站点的瓶颈會明顯後移。如果這时仍然吃紧,再考虑限速。
要限速,不要直接封禁
可以按来源 IP 设並發上限和每秒請求上限,超出後返回 429,並在 Retry-After 里给出建议等待時間。搜尋引擎的抓取程序對這種信号通常有反應,會相應放慢节奏,而不是立刻放弃整個站点。
返回 429 或 503,只是让蜘蛛慢一点;返回 403 或者長期的空頁面,等于告诉蜘蛛這個地址以後不用来了,两者的後果完全不同。
503 也可以配合 Retry-After 使用,适合整站维護或後端暂时不可用的场景。但要注意,5xx 持續出現會拉低蜘蛛對该站点的信任度,抓取频次可能被長期压低,想恢复比降下去更慢。
狀態碼要表達真實含义
- 200:内容正常返回。不要用它承载“系統繁忙”“請稍後再试”這類頁面,那會變成软 404。
- 429:短時間請求過多,建议稍後再来。
- 503:服務暂时不可用,配合 Retry-After 使用。
- 403:明确拒绝訪問,属于長期信号,慎用。
- 500:程序出错,蜘蛛會把它当成站点质量记錄在案。
把压力场景下的返回碼分清楚,比事後翻日誌排查要省事得多。
從源头减少無意义的抓取
限流和缓存都是被動應對,更省资源的方式是减少蜘蛛去抓那些没有價值的 URL:
- 篩選參數頁通過 robots.txt 或連結属性控制,避免组合爆炸;
- 站内搜尋结果頁、空结果頁不要暴露给蜘蛛;
- 分頁過深的列表頁做收敛,不要一路翻到几百頁;
- Sitemap 只放需要被發現的正式頁面,不要把參數變体都塞進去。
需要被發現的 URL 數量少了,抓取量自然會下来,服務器压力也随之下降。
把监控做在事後之前
建议在日誌里單獨統計蜘蛛請求的數量、平均响應時間和狀態碼分布,按天看趋势。响應時間開始抬升、5xx 比例上升,都是可以提前發現的信号。等到抓取中断再回头查,成本會高很多。
服務器稳定與否,最终决定的是蜘蛛能不能持續、完整地讀完站点。内容质量决定值不值得抓,稳定性决定抓得下来還是抓不下来。