记录一下那天晚上的排查过程。熔断进入 half-open 后一次放行 50 个请求做探测,下游刚恢复的实例又被压垮,重新熔断,来回震荡了 7 次,用户侧看到的是间歇性 502。
刚开始盯着「恢复判定只看一个成功请求就回到关闭态」,折腾了半个多小时,排掉了。
这类报错背后常见的原因有几处,逐个排除就行。半开放行量按总并发比例算,没有绝对上限。少数情况下是探测请求没有做慢速放量,一瞬间就把下游打满。
不容易想到的是,熔断状态存在本地内存,多个实例同时进入半开。
第一件事是确认当前半开放行配置
python -c "print({'half_open_max':50,'wait_s':30})"
然后改成逐个放行并加固定间隔
python -c "print({'half_open_max':3,'interval_ms':500})"
再往下把熔断状态收敛到共享存储
python -c "print('breaker_state=redis')"
剩下的就是用故障注入验证震荡是否消失
python chaos.py --target downstream --mode flaky --duration 120
改完先别撤,确认这几项。下游恢复过程中不再出现二次熔断,半开阶段只有一个探测请求在飞,用户侧 502 比例从 4.1% 降到 0.2%。
这里还有个坑。半开是恢复期的试探,不是第二次压测;放行量要给绝对值,多实例还得共享状态,否则每个实例都在各自试。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。
