搜索抓取

蜘蛛抓取高峰下的服务器承压:缓存、限速与状态码的处理

蜘蛛集中抓取时,服务器常出现响应变慢、5xx 增多的情况。本文从日志确认、缓存设置、限速策略、状态码选择到 URL 收敛,梳理站点在抓取压力下的处理顺序,帮助在不误封蜘蛛的前提下维持服务稳定。

搜索抓取

蜘蛛抓取高峰下的服务器承压:缓存、限速与状态码的处理

站点流量不大时,服务器对蜘蛛的抓取几乎无感。但当站内 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:

  1. 筛选参数页通过 robots.txt 或链接属性控制,避免组合爆炸;
  2. 站内搜索结果页、空结果页不要暴露给蜘蛛;
  3. 分页过深的列表页做收敛,不要一路翻到几百页;
  4. Sitemap 只放需要被发现的正式页面,不要把参数变体都塞进去。

需要被发现的 URL 数量少了,抓取量自然会下来,服务器压力也随之下降。

把监控做在事后之前

建议在日志里单独统计蜘蛛请求的数量、平均响应时间和状态码分布,按天看趋势。响应时间开始抬升、5xx 比例上升,都是可以提前发现的信号。等到抓取中断再回头查,成本会高很多。

服务器稳定与否,最终决定的是蜘蛛能不能持续、完整地读完站点。内容质量决定值不值得抓,稳定性决定抓得下来还是抓不下来。