很多人看到抓取日誌里成片的超时记錄,第一反應是服務器挂了。但登入机器一看,负载正常、CPU 空闲、磁盘也没满。這種情况多半不是可用性問题,而是速度問题:蜘蛛在等待响應的窗口内没有拿到足够的資料,就主動断開,轉去抓別的 URL 了。
可用性和响應速度是两件事。前者决定蜘蛛能不能连上,後者决定它愿不愿意等。慢,在抓取层面几乎等價于不可用。
日誌里的三類超时,含义並不相同
把超时笼统归成一類,排查會一直打轉。按發生阶段拆開看,至少有三種:
- 连接超时:TCP 握手阶段就没完成。常见于防火墙丢包、源站被限速、回源鏈路抖動。日誌里通常表現為连接建立失敗。
- 讀取超时:连上了,但等待响應体的時間過長。典型是後端接口阻塞、資料库慢查询、模板渲染卡住。
- 首字节延迟(TTFB)偏長:請求發出到第一個字节返回之間耗时明顯。它本身不一定触發超时,但會持續消耗蜘蛛的並發等待額度。
這三類的修复方向完全不同:连接超时找網絡與限流,讀取超时找後端逻辑,TTFB 偏長則要看缓存命中與動態渲染路径。混在一起看,容易得出“服務器不稳定”這種没有指向性的结论。
為什么慢會被直接放弃
蜘蛛的抓取是並發的,同时打開的连接數量有限。一個慢 URL 占住一個连接槽位,其他 URL 就得排队。当某個請求超過等待上限,蜘蛛不會一直守在那里,它會断開並把這個 URL 的失敗計入本次记錄。
後果是连鎖的:慢頁面被反复尝试、反复失敗,占用的額度却挤掉了本可以顺利抓取的其他 URL。久而久之,你會看到抓取總量下降,但抓取失敗的记錄集中在少數同一批 URL 上——這通常不是站点整体坏了,而是少數入口拖累了整体节奏。
常见慢点排查清單
- 列表頁或詳情頁存在未加索引的查询,資料量涨上来後單次响應從毫秒級退化到秒級。
- 頁面渲染依赖外部接口,且是串行調用,任一接口抖動都會拉長整体响應。
- 缓存命中率低,或缓存键设計過细導致几乎不命中,每次請求都走完整後端。
- 响應体本身過大,正文前置不足,蜘蛛讀到後面才拿到關键内容。
- 静態资源與 HTML 走同一套動態逻辑,图片、附件請求也在消耗應用進程。
- 回源带宽或出口被大流量任務占满,白天表現尤其明顯。
排查时建议按 URL 分组看响應时長分布,而不是只看站点平均值。平均值會被大量快頁面稀释,掩盖掉那批一直很慢的入口。
處理思路:分級,而不是全面提速
- 分級:把首頁、栏目頁、重要詳情頁列為高優先路径,确保它們走缓存或静態化;長尾頁、歷史归档可以接受稍慢。
- 砍掉串行:能並行取的資料並行取,能给預設值先渲染的就先渲染,不阻塞首字节。
- 设内部超时:给後端調用和資料库查询設定比蜘蛛等待上限更短的超时,让站点自己先降級返回,而不是把连接挂到蜘蛛放弃。
- 控制並發:對耗时較長的接口單獨限流,避免慢任務把應用進程池占满,连带影响快路径。
- 监控分位數:關注 P90、P95 响應時間,而不是平均响應時間。抓取放弃往往發生在尾部,而非中部。
和 429、503 不是一回事
429 和 503 是站点主動表達的“請慢一点”或“暂时不可用”,蜘蛛通常會據此調整抓取速率並稍後重试。超时則是被動断线,蜘蛛拿不到明确信号,只能按失敗處理,重试节奏也更难预测。
因此不要用超时来充当限流手段。想降速就明确返回 429 或 503,並配合合理的 Retry-After;靠拖時間逼退蜘蛛,只會让日誌里堆满無法解释的失敗。
如果同一批 URL 连續多天以超时形式失敗,先確認它們是不是共用了同一個慢接口或同一條資料查询,而不是急着換服務器。
值得長期观察的几個指标
- 抓取請求中成功响應的 P95 耗时,以及它随時間的趋势。
- 超时失敗占全部抓取請求的比例,按 URL 路径前缀分组。
- 缓存命中率與静態化覆盖率的變化。
- 同一 URL 在多次抓取中的耗时波動幅度,波動大往往意味着依赖了不稳定外部资源。
- 抓取總量與失敗總量之間的比值,用来判断是入口問题還是整体节奏問题。
抓取稳定性最终落在两件事上:让快路径一直快,让慢路径不要拖住別人。做到這两点,超时類失敗通常會明顯收敛,剩下的問题也更容易定位。