导读:本期聚焦于宋琮安创作的《Patroni如何与HAProxy整合实现PostgreSQL高可用负载均衡?》,敬请观看详情。数据库主从切换后,应用还在连旧的 主库,导致写入失败,这是PostgreSQL高可用架构里最典型的问题。Patroni虽然能自动完成故障转移,但它本身不负责流量分发,客户端依然需要知道该连哪个节点。将HAProxy放在Patroni集群前面,利用 Patroni提供的REST API健康检查接口,可以动态识别主节点与副本节点,读写请求自动路由到正确的数据库实例。本文详细讲解Patroni的健康检查端点原理、HAProxy的检测配置写法、读写分离的端口规划,以及结合keepalived避免HAProxy自身单点故障的完整方案,并附上可直接使用的配置示例与常见踩坑点。

PostgreSQL的高可用方案里,Patreon负责自动化故障转移,HAProxy负责流量分发,两者组合是目前比较主流的做法。但不少人在整合时会遇到一个关键问题:HAProxy怎么知道哪个节点是主库?如果健康检查配置不对,读写请求可能被发到只读副本上,直接报错。这篇文章围绕这个核心问题,把整合的原理、配置和注意事项讲清楚。

Patroni如何与HAProxy整合实现PostgreSQL高可用负载均衡?

一、Patroni的健康检查接口:整合的基础

Patroni为每个节点提供了REST API,默认监听在8008端口,这是HAProxy能够动态感知节点角色的关键。不同的HTTP端点返回不同的信息,HAProxy正是通过访问这些端点的返回码来判断节点的身份和状态。

最常用的几个端点如下:/master只在当前节点是主库(leader)时返回200,否则返回503;/replica只在节点是正常副本时返回200;/replica?lag=16MB additionally会检查复制延迟,延迟超过16MB就认为不健康,这个参数对读一致性要求高的场景很有用;/read-only则主库和副本都会返回200,适合做只读连接池的后端检测。

理解这些端点非常重要,因为HAProxy的配置本质上就是把HTTP检查规则映射到不同的监听端口上。一个常见的错误是用TCP端口5432做健康检查,这只能确认PostgreSQL进程活着,无法区分主从角色,切换之后流量依然会打到已经降级为副本的旧主库上,导致写请求全部失败。

二、HAProxy配置:读写分离的端口规划

整合的常规做法是给HAProxy规划多个监听端口,比如5000端口只转发到主库,5001端口转发到所有副本,5002端口读写都可以。应用端根据业务性质选择连接哪个端口,写请求连5000,读请求连5002或5001,这样就实现了透明的读写分离。

下面是一份可以直接参考的配置,假设三个节点分别为pg1、pg2、pg3:

global
    maxconn 10000
    log /dev/log local0

defaults
    mode tcp
    timeout connect 5s
    timeout client 30m
    timeout server 30m

listen postgres_master
    bind *:5000
    option httpchk
    http-check expect status 200
    default-server inter 3s fall 2 rise 2
    server pg1 192.168.1.11:5432 check port 8008 check-http-GET /master
    server pg2 192.168.1.12:5432 check port 8008 check-http-GET /master
    server pg3 192.168.1.13:5432 check port 8008 check-http-GET /master

listen postgres_replicas
    bind *:5001
    option httpchk
    http-check expect status 200
    balance roundrobin
    default-server inter 3s fall 2 rise 2
    server pg1 192.168.1.11:5432 check port 8008 check-http-GET /replica
    server pg2 192.168.1.12:5432 check port 8008 check-http-GET /replica
    server pg3 192.168.1.13:5432 check port 8008 check-http-GET /replica

listen postgres_read_only
    bind *:5002
    option httpchk
    http-check expect status 200
    balance roundrobin
    default-server inter 3s fall 2 rise 2
    server pg1 192.168.1.11:5432 check port 8008 check-http-GET /read-only
    server pg2 192.168.1.12:5432 check port 8008 check-http-GET /read-only
    server pg3 192.168.1.13:5432 check port 8008 check-http-GET /read-only

几个配置细节值得注意。首先,代理数据库流量必须用mode tcp,HAProxy不做协议解析,只是四层转发。其次,check port 8008指定健康检查走Patroni的REST API端口,而实际转发的连接仍然指向5432,检查端口和数据端口分开是这套方案的精髓。再次,http-check expect status 200配合check-http-GET /master保证了只有主库返回200时才会被标记为可用。

关于检测频率,inter 3s fall 2 rise 2表示每3秒检测一次,连续两次失败就摘除节点,连续两次成功再恢复。这个时间要和Patroni的loop_waitttl参数配合调整。如果检测太频繁,主从切换的瞬间可能出现短暂的双主视图;如果太稀疏,切换完成后应用要等更久才能恢复写入。一般建议failover总收敛时间控制在10到15秒以内。

三、HAProxy自身的单点问题:结合keepalived

上面的架构解决了数据库层的故障转移,但HAProxy本身成了新的单点。一旦HAProxy所在机器宕机,整个集群对应用来说就不可用了。标准解法是部署两台HAProxy,配合keepalived浮动一个虚拟IP,应用统一连这个VIP。

keepalived的核心配置是在两台机器上配置相同的VIP,优先级不同,通过VRRP协议协商由谁持有VIP。同时给keepalived加一个检测脚本,定期确认本机HAProxy进程存活,如果HAProxy挂了就主动降低优先级,把VIP漂移到另一台机器:

vrrp_script chk_haproxy {
    script "killall -0 haproxy"
    interval 2
    weight 2
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    virtual_ipaddress {
        192.168.1.100/24
    }
    track_script {
        chk_haproxy
    }
}

备用节点上把state改为BACKUP、优先级设为90即可。这样最终架构是:应用连VIP的5000或5001端口,VIP落在其中一台HAProxy上,HAProxy通过Patroni API感知主从角色并转发到正确的PostgreSQL节点。任何一层发生故障,整个链路都能自动恢复,无需人工干预。

四、常见踩坑点与优化建议

第一, Patroni的REST API开启了认证时,HAProxy的健康检查也要带上认证头,可以用http-check send meth GET uri /master hdr Authorization\ Basic\ xxx的写法(较新版本语法),否则所有节点都会被判定为不健康。第二,应用连接池要注意tcp模式下长连接的角色漂移问题:客户端通过5000端口建立的连接,在切换后旧连接可能还挂在旧主库上,建议应用侧开启target_session_attrs=read-write(libpq驱动)或在连接出错时强制重建连接。第三,option http-keep-aliveoption httpchk的组合在老版本HAProxy上有兼容性问题,建议使用1.8以上版本。

另外,Patroni配合pgbouncer做连接池时,HAProxy应该放在pgbouncer前面,而不是直接怼到PostgreSQL上,这样能避免故障切换瞬间连接风暴打满数据库的max_connections。监控方面,可以在HAProxy的listen段加上stats enable开启状态页,观察后端节点的健康状态变化,排查切换问题时非常有用。

总结一下,Patroni加HAProxy的整合核心就一句话:让HAProxy用Patroni的REST API做七层健康检查,用不同端点区分主从角色,再用多端口规划实现读写分离,最后用keepalived补齐HAProxy自身的高可用。把这套架构理顺之后,PostgreSQL集群的自动化运维会轻松很多。

PatroniHAProxyPostgreSQL高可用修改时间:2026-09-12 23:22:38

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260912/55617.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。