这类问题我又碰上了一次。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 也没有明显变差。
限流类状态码必须从重试名单里排除,重试只对瞬时故障有意义,对配额问题来说重试就是把小火苗吹成火灾。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。
