22 四通八达:服务接入、连接池与路由
应用需要的不是“连接 10.10.10.11”,而是:
机器地址只回答“TCP 包送到哪里”,服务端点还必须回答:
只要其中一项没有写清,端口号就是一个未经定义的偶然实现。
本章把 PostgreSQL backend、PgBouncer、HAProxy、Patroni 和客户端驱动放进
同一条证据链。学习顺序不是先背 5433/5434/5436/5438,而是先定义服务
语义,再计算连接预算,选择池化模式,最后验证 Pigsty 的具体映射与切换行为。
本章目标
完成本章后,你应当能够:
- 把连接 URI 当作版本化服务合同,而不是主机别名;
- 区分主写、只读、同步读取、离线读取和直连管理端点;
- 解释异步副本为什么不能天然提供 read-your-writes;
- 用 LSN、sticky-primary 或业务一致性 token 设计读取策略;
- 说明一个 PostgreSQL backend 的进程、内存、锁、事务和会话成本;
- 拒绝用调大
max_connections代替容量规划; - 把应用进程数、应用池、PgBouncer pool 与数据库保留槽放进同一预算;
- 正确比较 session、transaction 与 statement pooling;
- 判断临时表、会话 GUC、
LISTEN、咨询锁和安全上下文是否兼容事务池; - 区分协议级 prepared statement 与 SQL
PREPARE; - 从
SHOW POOLS证明排队、复用与服务端连接上限; - 阅读 HAProxy 的 Patroni 角色健康检查、backup 选择和连接关闭策略;
- 为切换中的断连、退避、抖动和提交结果未知编写客户端合同;
- 识别角色已经正确、但池化后端仍保留旧角色状态的情况;
- 在 Pigsty 中声明、渲染、校验和重载服务,而不是手改产物;
- 完成一次带端点、池化、异步可见性和双向计划切换的可重放演练。
前置与后续
前置:
- 第 18 章 PostgreSQL 数据平台与替代边界 已定义服务、SLO 和 责任边界;
- 第 19 章 部署基线 已固定 exact Pigsty v4.5.0 四机沙箱;
- 第 20 章 高可用 已解释 Patroni、timeline、 计划切换与提交结果未知;
- 第 21 章 备份体系与恢复演练 已证明 HA、backup 和 service recovery 不能互相替名;
- 读者已掌握 Linux、SQL、事务、锁和基本网络连接概念。
后续:
- 第 23 章把身份、HBA、TLS、RLS、审计与池化上下文纳入安全模型;
- 第 24 章把端点合同、切换 SOP 和例外变成组织治理;
- 第 25、26、27 章分别补齐指标、容量压测与参数治理;
- 第 31、34 章会复用本章的 queue、timeout、reserve 与 reconnect 控制点 处理事故和过载。
学习路径
这条路径故意把“端口”放在后面。5433 不是 PostgreSQL 标准语义;只有
当声明、渲染配置、健康检查、池状态和 SQL 观察相互吻合时,它才是当前
环境里的主写服务。
五层连接证明
| 层 | 要回答的问题 | 本章证据 |
|---|---|---|
| 声明 | 服务本来应当选择什么 | Pigsty inventory/defaults、ADR |
| 渲染 | 实际代理与池配置是什么 | HAProxy service file、SHOW CONFIG |
| 运行 | 当前哪些 backend 合格、池是否排队 | Patroni、HAProxy health、SHOW POOLS |
| SQL | 客户端最终落到什么角色与会话 | recovery/read-only、PID、GUC、token |
| 故障 | 角色变化时确认/未知结果如何收敛 | client event、timeline、token reconcile |
任意一层单独通过都不够:
Pigsty 默认服务语义
本章 exact v4.5.0 沙箱保留四个服务:
| 名称 | 入口 | 目标 | Patroni 检查 | 本章用途 |
|---|---|---|---|---|
| primary | 5433 | 当前主库 PgBouncer :6432 | /primary |
短 OLTP 读写 |
| replica | 5434 | 副本优先 PgBouncer :6432 | /read-only |
可容忍陈旧的只读 |
| default | 5436 | 当前主库 PostgreSQL :5432 | /primary |
管理、迁移、会话敏感工具 |
| offline | 5438 | 指定离线副本 PostgreSQL :5432 | /replica |
受控 OLAP/ETL |
replica 的 primary 是 backup,offline 的普通 replica 也是 backup。
因此名称表达“选择偏好与降级策略”,不是永恒承诺。客户端仍要用
target_session_attrs、只读事务和业务策略防止错误落点。
这些都是可修改的 Pigsty 默认值,不是 PostgreSQL 标准端口。实际系统必须 读取自己的声明与渲染产物。
正式实验
池化实验临时把入口节点的默认 server pool 从:
改为:
所有值在角色切换前精确恢复。正式观测:
最重要的观测不是某个毫秒数字,而是一个跨层失配:
pg-test-2的 PostgreSQL 已经是只读副本,Patroni 和 HAProxy 健康检查 也正确,但 PgBouncer 的既有 pool 仍可能保留上一次角色周期的状态。RECONNECT test让服务端连接重新发现当前角色,端点验证才重新通过。
正式切换因此把三节点 RECONNECT test 计入恢复路径,并要求刷新后出现新的
确认写入。它不是隐藏的实验准备,更不是生产 SLO。
结论边界
十四项例外
沿用第 19 章六项与第 20 章四项,本章新增:
本章目录
22.1 服务端点的语义
22.2 连接的服务端成本
22.3 PgBouncer 池化模式
- 22.3.1 session、transaction、statement pooling
- 22.3.2 临时表、会话 GUC、监听与咨询锁
- 22.3.3 预备语句支持必须绑定 PgBouncer 与驱动版本
- 22.3.4 池等待、服务时间与背压
22.4 路由与故障切换
22.5 连接预算与过载边界
22.6 Pigsty 服务接入层
22.7 实战:写入、只读与管理三类接入
实验入口
lab-contract.md:风险、动作、停机线与解释边界;requirements.json:机器验收合同;endpoint-contract.json:四类端点语义;routing-adr.md:路径、池化与切换决策;topology.mmd:实验拓扑;task.sh:唯一安全入口;connection-run.json:正式参考结果;negative-cases.json:十五个反例。
task.sh all 只重验既有证据,不连接 fixture、不改配置、不切换角色,也不
删除对象。drill:service 和 reset:fixture 是两条独立、精确守卫的路径。
参考资料
- PostgreSQL 18:连接与认证参数
- PostgreSQL 18:libpq 连接参数与 target_session_attrs
- PgBouncer:Configuration
- PgBouncer:Feature map
- PgBouncer:Administration console
- Pigsty:PostgreSQL Service
- HAProxy:Health checks
上一章:未雨绸缪:备份体系与恢复演练 · 返回下卷导读 · 下一章:固若金汤:认证、授权与数据安全 · 查看全书目录 · 查看索引中心