搜索抓取

蜘蛛把源站压满时:503、429 与 Retry-After 怎么用

源站被蜘蛛压满时,直接返回 500 或掐断连接都不是好办法。本文讲清 503、429 与 Retry-After 各自适合什么场景、如何按路径或 UA 做分流限速,以及这些状态码与抓取预算之间的关系,让抓取压力变得可控、语义变得清晰。

搜索抓取

蜘蛛把源站压满时:503、429 与 Retry-After 怎么用

抓取压力上来的时候,源站最先感受到的是连接数和 CPU。有些站点一遇到蜘蛛密集访问就直接返回 500,或者干脆把连接掐掉。结果往往是:蜘蛛没少来,只是白跑一趟,下一次来得更没规律。

其实 HTTP 状态码本身就是一套跟蜘蛛沟通的语言。用对了,它可以告诉蜘蛛现在别来、或者慢一点;用错了,反而会放大损耗。

先分清几种状态码在说什么

  • 200:内容正常。如果返回的是一个系统繁忙提示页,蜘蛛会把它当成正常内容收走,等于把一个无意义页面放进了索引。
  • 404 / 410:页面确实不存在。410 比 404 更明确,蜘蛛通常更快把它从待抓队列里划掉。
  • 500:服务端内部错误。蜘蛛会认为这是临时故障,过一阵再来,但长期大面积 500 会拖低它对站点的信任度。
  • 503:服务暂时不可用。这是最合适的、表达我现在真的扛不住的方式。
  • 429:请求太多。偏向于表达你请求频率超了,请放慢。

503 的正确用法:带上 Retry-After

单独返回 503 只说明了不可用,没有说明多久之后可以来。加上 Retry-After 响应头,语义才完整:

HTTP/1.1 503 Service Unavailable,响应头中包含 Retry-After: 3600

这个值可以是秒数,也可以是一个 HTTP 日期,意思是这个时间之后再试。对搜索引擎蜘蛛来说,这比断连和超时友好得多:它至少知道该等多久,而不是靠猜。

有几个边界要注意:

  • Retry-After 不要给得过长。几小时量级可以接受,动辄几天容易让蜘蛛把整个站点的抓取频率调低。
  • 不要长期全站 503。持续返回 503 的站点,蜘蛛会逐步减少抓取,恢复之后也需要一段时间才把频率加回来。
  • 能按路径分就按路径分。评论提交、站内搜索接口、下单流程这些不需要被抓的路径返回 503,正文页面保持 200,比全站一起挡更划算。

429 更适合做细粒度限速

如果说 503 是整体关门,429 更像是你这一路走得太快。按 UA 或按来源 IP 做限速时,超出的请求返回 429,再配上 Retry-After,比直接返回 403 更清楚:403 意味着你没资格,429 意味着稍等再来,后者不会让蜘蛛误判页面的可访问性。

实践中可以这样分层:正常抓取放行,短时间内超过阈值的返回 429 加一个较短的 Retry-After,源站整体压力过大时再切到 503。层次分明,蜘蛛也容易读懂。

和抓取预算的关系

抓取预算不是一份固定配额,蜘蛛会根据抓到的内容有没有价值、站点响应是否稳定来动态调整。一个延迟忽高忽低、时不时冒出 5xx 的站点,即便 URL 数量很多,也很难拿到高频抓取。反过来,响应稳定、状态码语义清晰的站点,蜘蛛更愿意多花时间。

所以限速的目的不是把蜘蛛赶走,而是让每一次抓取都有结果。请求被 503 挡回去,和请求超时被掐断,看起来都是没抓到,但对蜘蛛留下的印象完全不同。

落地时容易踩的几个坑

  1. 用 200 返回错误页。蜘蛛会当成正常页面反复来抓,白白消耗预算。
  2. 返回 503 却不给 Retry-After。蜘蛛只能按默认策略重试,节奏未必是你想要的。
  3. 把 500 当限速手段。500 代表我出故障了,长期使用会拖低整站抓取稳定性的评价。
  4. 防护规则误伤正常蜘蛛。限速生效后,最好在日志里按 UA 抽样看一遍,确认被拦的是高频异常请求。
  5. 恢复之后什么都不做。流量回稳后,可以用 Sitemap 或者站内入口重新把重点 URL 推到蜘蛛面前,别指望它立刻自己找上门。

小结

源站能不能稳定响应,是抓取路径里最基础的一环。状态码用对了,等于在蜘蛛和你之间留了一条明确的沟通通道:忙的时候说清楚忙多久,不忙的时候保持干净利落的 200。剩下的 URL 发现和内链结构,才有条件发挥作用。