先看现象。Nginx 限流设成每秒 2 个请求,蜘蛛一次抓 30 条时会瞬间超过阈值,拿到 429 之后被 fail2ban 拉黑一小时,日志里整段时间该 IP 全是空响应。

原因不止一个,得分开看。limit_req 的 burst 设为 0,任何突发都被直接拒绝。少数情况下是fail2ban 把 429 计入错误,触发封禁。

少数情况下是蜘蛛与用户共用同一个限流桶,没有分桶。

第一件事是查当前限流配置与突发值

grep -rn 'limit_req' /etc/nginx/ | head

然后按 UA 分桶并给蜘蛛更大 burst

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

等前面都确认过,再把 429 从 fail2ban 规则里排除

grep -n '429' /etc/fail2ban/jail.local

同一份数据我导出了两份,一份留底,一份拿来试。

这类问题以前遇到过,但这次的触发条件和上次不一样。

怎么算真的好了,看的是同一批现象。分桶并调大 burst 后,蜘蛛请求不再出现 429,封禁记录清零,抓取量回到正常水平。

这里还有个坑。限流要按来源分桶,蜘蛛和真实用户的行为模式完全不同,一个桶装不下两种流量。报错文案容易误导,真正的原因往往在相邻那一层的日志里。

作者 9823189