报错是这么冒出来的。Kong 3.6 网关前面挂了 20 个业务方,rate-limiting 插件配了 per consumer 每分钟 60 次,压测时单个 consumer 打到 200 次仍然放行,请求看起来都算到了同一个匿名 consumer 上。

中间走过弯路,把「policy 用了 local 多节点各自计数」当成主因,改完现象没变。

真正麻烦的地方在于,几个原因的现象几乎一样。请求没带 consumer 标识 插件按 IP 归类。也可能是key-auth 插件没启用 拿不到 consumer。

少数情况下是限流窗口与上游配额不同步。

第一件事是查插件实际生效的配置

curl -s http://127.0.0.1:8001/plugins | jq '.data[] | select(.name=="rate-limiting")'

然后启用 key-auth 让 consumer 可识别

curl -s -X POST http://127.0.0.1:8001/consumers -d username=team_a

随后把 policy 改成 redis 统一计数

curl -s -X PATCH http://127.0.0.1:8001/plugins/$PLUGIN_ID -d 'config.policy=redis'

剩下的就是用同一 key 连发 70 次验证

for i in $(seq 1 70); do curl -s -o /dev/null -w '%{http_code} ' -H 'apikey: team_a_key' http://127.0.0.1:8000/v1/chat; done

当时还开着另一个排查窗口,两边日志对照着看才定位到。

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

恢复的判定其实很直接。第 61 次开始返回 429,另一个 consumer 的 key 仍能正常通过,Redis 里的计数按 consumer 分开。

容易忽略的是,local 策略只在单节点准确,多副本网关必须用 redis 或 cluster,否则总量会翻倍。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。

作者 9823189