机房被打之后加了一条按 UA 的限流,rate 设成 1r/s,burst 为 5。一周后百度抓取量从日均 6000 次掉到 1100 次,日志里大量 503 落在百度请求上,Googlebot 也掉了一半。

一开始怀疑是「没有给已知蜘蛛做白名单,正常抓取和攻击流量一起被限」,查了一圈,方向不对。

真正麻烦的地方在于,几个原因的现象几乎一样。限流的 key 用了 $http_user_agent,蜘蛛的完整 UA 全被算成同一来源。还有一种是burst 设得太小,蜘蛛并发稍高就被直接拒绝。

另外,限流规则写在 server 段 蜘蛛与攻击流量共用同一个桶。

上来先按 UA 统计被拒的比例

awk '$9==503 && $0 ~ /Baiduspider/' access.log | wc -l

给蜘蛛段单独放行不做限流

map $http_user_agent $limit_key { default $binary_remote_addr; ~*Baiduspider ""; ~*Googlebot ""; }

调整限流桶大小再观察

limit_req_zone $limit_key zone=bot:20m rate=10r/s;

剩下的就是对比限流前后的抓取条数

grep -c 'Baiduspider' access.log

改完先别撤,确认这几项。放开白名单后 503 不再出现在蜘蛛请求上,五天后百度抓取量回到 5200 次,正文页的收录速度同步恢复。

容易忽略的是,限流要按真实攻击特征设 key,用完整 UA 做维度会把所有蜘蛛流量压成一个来源,等于自断抓取。这类问题最好一次改到位,反复小改反而容易把原因搅混。

作者 9823189