先看现象。10 月 30 日凌晨一个自称 Googlebot 的 UA 每秒发来 200 多次请求,CPU 直接打满,按 IP 限流之后真蜘蛛也被一起挡掉。

把日志和配置对完,能解释这个现象的基本就这几处。只按 UA 限流会被伪造,UA 字符串是最容易抄的字段。另一种情况是只按 IP 限流会误伤 NAT 出口,多个真实用户共用同一地址。

少数情况下是日志里没有做正反向解析校验,真假蜘蛛根本分不出来。

不容易想到的是,限流阈值写死在 Nginx 全局,静态资源请求也被一起算进去。

第一件事是用正反向解析确认蜘蛛身份

dig -x 66.249.66.1 +short

再往下按 UA 加 IP 段做两级令牌桶

limit_req_zone $binary_remote_addr zone=spider:10m rate=5r/s;

给静态资源单独放开一条规则

location ~* \.(css|js|png|jpg)$ { limit_req off; }

末了用真实蜘蛛 IP 复验是否被误拦

curl -A 'Mozilla/5.0 (compatible; Googlebot/2.1)' -sI https://www.example.com/ | head -1

恢复的判定其实很直接。两级限流上线后,伪造 UA 的请求被压到每秒 3 次以下,真蜘蛛的抓取量没有下降,CPU 峰值回到 40%。

限流规则要留一条只针对已验证蜘蛛的放行名单,否则大促或密集抓取时最先被拒的就是真蜘蛛。报错文案容易误导,真正的原因往往在相邻那一层的日志里。

作者 9823189