nginx四层代理数据库+keepalived热备需严守三要点:启用stream模块、编写双层健康检查脚本(端口+db连通性)、主备vrrp配置严格一致,否则易脑裂或vip不漂移。

直接用 Nginx 做四层代理转发数据库流量(如 MySQL 3306、PostgreSQL 5432),再搭配 Keepalived 实现主从热备,是中小型系统里成本低、见效快的高可用方案。关键不是“能不能做”,而是配置必须严丝合缝——尤其是健康检查、VRRP 同步和 stream 模块启用这三处,错一个就可能脑裂或 VIP 不漂移。
确认 Nginx 已启用 stream 模块
Nginx 默认编译不包含 stream 模块,而四层代理必须依赖它。yum 安装的版本在 CentOS 8+/openEuler/麒麟 V10 等新系统中通常已内置;但源码编译或旧版需手动加 --with-stream 参数。验证方式:
- 执行 nginx -V 2>&1 | grep -o with-stream,有输出即支持
- 若无,需重新编译或换用带 stream 的包(如 EPEL 提供的 nginx-all-modules)
- 配置中 stream { ... } 必须位于最外层,不能嵌套在 http 块内
编写可靠的健康检查脚本
Keepalived 不能直接判断 Nginx 的 stream 服务是否真正在转发数据库请求,必须靠外部脚本探测后端 DB 是否可达 + Nginx 进程是否存活。推荐脚本逻辑:
- 用 nc -z 127.0.0.1 3306 检查本地监听端口是否通(验证 Nginx stream 正常工作)
- 再用 mysql -h192.168.50.111 -P3306 -uhealth -p'pwd' -e "SELECT 1" &>/dev/null 验证能穿透代理连上真实 DB
- 脚本返回 0 表示健康,非 0 触发 Keepalived 降权或切换
- 把脚本路径写入 keepalived.conf 的 vrrp_script,并绑定到实例中
Keepalived 主备配置要点
两台 Nginx 服务器配置几乎一致,仅 state 和 priority 不同。核心项必须严格对齐:
- virtual_router_id:主备必须相同(1–255 范围内),否则无法形成 VRRP 组
- advert_int:主备心跳间隔一致(建议 1 秒)
- authentication:密码类型(PASS)和密码值完全一样
- track_script:调用同一健康检查脚本,且 timeout、interval 等参数同步
- 主节点 priority 设为 100,备节点设为 90;当主节点脚本连续失败 3 次,优先级降为 0,VIP 自动漂移到备机
避免脑裂的实操建议
数据库代理场景下脑裂极其危险——主备同时持有 VIP,客户端连接可能随机落到任一节点,导致事务中断或双写冲突。预防措施要落地:
- 关闭防火墙或放行 VRRP 组播地址 224.0.0.18(协议 112)
- 主备之间用独立网卡或 VLAN 做心跳线(不共用业务网卡)
- 在 keepalived.conf 中添加 nopreempt(仅备机配置),防止主恢复后抢回 VIP 导致抖动
- 部署后手动断网测试:拔掉主机业务网线,观察 VIP 是否 3 秒内迁移,且 ip a 显示备机已绑定











