下游一次 500 毫秒超时,客户端重试 3 次,网关层再重试 2 次,单次请求在下游实际产生 9 次调用。故障 1 分钟下游 QPS 从 1200 冲到 1.1 万,本来只是慢,最后直接被打挂。乍看像缓存或者权限的锅,追下去往往不是。
grep -rn 'maxAttempts\|retry' config/ | grep -v test curl -s localhost:8081/actuator/metrics/resilience4j.retry.calls | jq '.measurements'
追下去是这么回事:重试发生在多个层级,每层都以为自己只放大三倍,叠起来是乘法。重试条件也没排除超时,这类失败大概率重试也不会成功。
碰到「重试放大流量」这类问题,我习惯先把当前配置原样备份一份,改坏了立刻换回来,不用现场推。测试环境和线上的差别,往往就在版本号和那几行被忽略的配置上。
线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。
具体做法是,全链路只保留一层重试 放在最靠近业务的那一侧;只对连接失败和 5xx 重试 超时不重试;加重试预算 单实例每秒重试不超过正常流量的 10%;重试间隔用指数退避并加随机抖动。
验收就看一点,下游故障时 QPS 峰值不超过正常值的 1.2 倍,超时类失败不再触发重试。
