概述
所有依赖共用一个大连接池会把故障耦合在一起。报表查询变慢时会持续占用连接,直到池被耗尽,健康的支付请求只能排在后面等待。舱壁模式为每个依赖分配固定容量和有限等待时间,某个分区饱和时调用方快速失败或降级,而不是拖垮整个进程。
步骤
- 为每个依赖建立独立连接池,显式设置最大连接数和等待超时:
export const paymentsPool = new pg.Pool({
connectionString: process.env.PAYMENTS_DATABASE_URL,
max: 8,
connectionTimeoutMillis: 500,
});
export const reportsPool = new pg.Pool({
connectionString: process.env.REPORTS_DATABASE_URL,
max: 4,
connectionTimeoutMillis: 500,
});
- 导出每个池的 total、idle、waiting 指标,
waiting持续大于 0 超过一分钟即告警。 - 用
toxiproxy-cli toxic add reports-db -t latency -a latency=2000只给报表库注入延迟,再跑混合流量。 - 观察支付接口 p95 是否保持不变;若也上升,说明仍有共享的池、HTTP agent 或线程池未隔离。
验证
预期报表请求在 500 毫秒后快速失败或明显变慢,而支付请求延迟曲线平稳。仪表盘上两个池的饱和度应独立变化,日志中能看到池名称,便于定位是哪一个依赖饱和。
注意事项
- 所有池的 max 之和必须低于数据库
max_connections的 80%,给管理会话留余量。 - 连接必须在 finally 中释放,或使用统一的事务封装,否则池会被缓慢泄漏耗尽。
- 舱壁只改变失败范围,不增加容量;持续饱和应扩容或优化查询。
- 静态切分在流量结构变化时可能浪费容量,需按季度复核池大小。