Bulkhead Isolation
解释如何通过独立连接池、并发配额、队列或 worker pool 隔离资源,避免一个慢依赖或租户耗尽整个服务的共享容量。
#concept
#growing
#backend
#reliability
[!info] related notes
- 所属 MOC:Reliability Engineering MOC
- 相邻概念:Circuit Breaker、Backpressure、Rate Limit
- 关系总览:云原生弹性设计
Bulkhead Isolation
[!abstract] 一句话定义 Bulkhead(舱壁隔离)把线程、连接、并发槽位、队列或进程划分为相互独立的资源池,使一个慢依赖或高流量租户耗尽自己的预算时,不会拖死整个服务。
一个典型故障
Service calls:
├─ payment API (healthy)
├─ recommendation API (slow)
└─ email API (healthy)
all share one 100-thread pool
→ recommendation occupies 100 threads
→ payment and email also stop
如果为不同依赖设置独立并发池:
payment: 40
recommendation: 20
email: 20
reserved/system: 20
推荐调用最多占用该池的 20 个槽位;这不等于所有资源都已隔离,共享数据库连接、内存或 CPU 仍可能被拖垮。队列也必须有界,不能把池外等待转成无限积压。
常见隔离维度
- 每个下游独立连接池;
- 每类任务独立 Worker Pool / Queue;
- 高/低优先级独立容量;
- 每个租户或模型 Provider 独立并发配额;
- 独立进程、容器、节点池;
- 独立数据库实例或 Shard;
- Agent Tool / Run Class 独立执行池。
隔离通常增加预留容量与运维成本,也可能因池间闲忙不均降低资源利用率;实际取舍取决于负载和共享资源,因此需要根据故障影响分层。
与相邻模式的区别
| 模式 | 主要控制对象 |
|---|---|
| Bulkhead | 资源池和故障域 |
| Circuit Breaker | 是否继续调用持续失败的依赖 |
| Rate Limit | 新请求进入速率/配额 |
| Backpressure | 下游容量不足时的在途流量 |
| Timeout | 单次等待上限 |
这些模式互补:Bulkhead 限制“最多拖累多少资源”,Circuit Breaker 决定“是否暂时停止调用”。
粒度如何选择
不必给每个 Endpoint 单独线程池。通常优先隔离:
- 延迟分布明显不同的依赖;
- 高风险、低可信第三方;
- 高成本模型或工具;
- 批处理与在线请求;
- 高优先业务与可延迟任务;
- 不同租户之间需要配额保护的资源。
饥饿与容量浪费
隔离可能造成:
- A 池空闲,B 池排队;
- 预算过小导致正常峰值被拒绝;
- 池太多导致配置和监控复杂;
- 共享下游仍然是最终瓶颈。
可使用“保底独立 + 可借用弹性容量”,但应限制新增借用并保留保底容量。已运行的工作不一定能立即抢占,不能假设超时返回就释放了实际占用;槽位释放要与工作真正结束或受控终止一致。
观测重点
每个隔离池至少观察:
active / queued / rejected
wait time / execution time
pool saturation
connection acquisition latency
per-dependency error and timeout
borrowed vs reserved capacity
只看全局 CPU 无法判断哪个依赖正在耗尽共享资源。
设计检查表
- 已识别最可能造成级联故障的依赖和任务类。
- 在线与批处理工作拥有不同容量边界。
- 每个池有 Queue 上限、Timeout 和拒绝策略。
- Pool Saturation 可观测并能关联具体依赖。
- 隔离失败后有 Fallback / Degradation,而不是无限排队。
- 定期根据真实流量调整,而不是永久硬编码拍脑袋数字。