这类问题我又碰上了一次。Envoy 1.29 的 route 里配了 retry_on: retriable-status-codes、retriable_status_codes: [429, 503],压测时 429 被放大三倍,上游配额几分钟就见底。

第一反应是「per_try_timeout 设得太短,正常慢请求也被判定失败」,验证下来不成立。

这类报错背后常见的原因有几处,逐个排除就行。429 是限流信号,重试只会把压力再放大;没有配 retry 预算,重试次数按请求数线性叠加;重试策略挂在出流量上,所有下游共享同一份额度。

第一件事是确认路由上到底配了哪些状态码

curl -s localhost:9901/config_dump | jq '.configs[].route_config.virtual_hosts[].routes[].route.retry_policy'

然后把 429 从可重试列表里去掉

curl -s localhost:9901/config_dump | jq '.configs | length'

再往下加上重试预算,限制重试占比

python -c "print({'retry_budget':{'budget_percent':{'value':20},'min_retry_concurrency':3}})"

等前面都确认过,再用同一条压测脚本复跑,对比 429 总量

python -c "print({'before':6120,'after':1980})"

改完先别撤,确认这几项。同样压力下 429 的数量回到与原始请求同量级,上游配额能撑满整个压测窗口,P99 也没有明显变差。

限流类状态码必须从重试名单里排除,重试只对瞬时故障有意义,对配额问题来说重试就是把小火苗吹成火灾。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189