背压
向上游发慢信号,而非无界排队或丢请求。
为什么
当下游慢,选项:排队(内存涨、延迟无界升)、丢(请求失败)、或推回(叫调用者慢)。背压是第三项且唯一优雅降级——系统慢而非破。无它,慢 DB 致每个 API 实例排 1 万请求、耗内存、OOM 崩、整服务挂。有背压(HTTP 429、队列深度限、响应式流),API 早拒、存活、DB 恢复时恢复。是慢服务与死服务之差。
何时使用
任何调更慢下游或收突发流量的服务。半天。仅温和流量的内部服务可跳过。
如何做
1. 每实例设最大在途请求(如 200);超则 429 + Retry-After 拒 2. 下游调用用有界队列(非无界);满则快失败 3. 传播背压:下游返 429 则向调用者返 429(别排队) 4. 用断路器:N 次失败后停调冷却,后半开测试 5. 流式用响应式流(经 request(n) 信号背压) 6. 过容量压测:确认服务返 429 且存活,非 OOM
示例
API 依赖 DB,DB 慢到 2 秒/查询: 无背压: API 排 1 万请求 → 内存 4GB → OOM → 服务挂 有背压: max_in_flight = 200;第 201 → 429 + Retry-After: 5 DB 慢 → 在途满 → API 对新请求返 429 客户端退避(Retry-After)→ 队列排空 → DB 恢复 → 200 恢复 服务全程存活,只是降级。
常见问题
- ⚠用无界队列"为安全"——恰相反;把慢下游转成 OOM。永远有界队列。
最佳实践
- ✓返 429 带 Retry-After 头,非 500——429 告客户端退避;500 告它坏了。
- ✓在途限按路由可配——健康检查不该与用户请求争槽。