Keepalived + VIP 高可用架构设计与实践详解:实现 Nginx 入口层的高可用

一、背景与目标

在大型网站或企业系统中,“高可用性(High Availability, HA)”是衡量系统稳定性的关键指标之一。任何一个节点故障都不应影响整体服务的可达性。

问题背景举例:

  • Tomcat 部署了集群(后端高可用)
  • Redis 配置了主从 + Sentinel(缓存高可用)
  • 数据库使用了主备或分库分表(存储高可用)
  • 但入口 Nginx 只有一个……

Nginx 宕机 = 全站瘫痪

为了解决这个“最顶层的单点问题”,我们引入:

Keepalived + VIP 架构:实现 Nginx 入口层的高可用


二、架构原理

2.1 什么是 Keepalived?

  • Keepalived 是一个运行于 Linux 平台的高可用服务组件。
  • 利用 VRRP 协议(虚拟路由冗余协议) 在主备节点间漂移 IP 地址(VIP)。
  • 可结合健康检查脚本实现服务层探测。

2.2 什么是 VIP?

  • VIP(Virtual IP):不属于某台服务器的真实 IP。
  • 它在主机之间漂移,由 Keepalived 管理。
  • 客户端只访问 VIP,永远感知不到背后是哪一台服务器处理请求。

三、Keepalived + VIP 架构工作机制详解

3.1 主备模型说明

                 +------------------+
                 |     客户端       |
                 +------------------+
                          |
                          v
                    [ 虚拟IP: VIP ]
                          |
               -------------------------
              |                         |
        +-------------+         +-------------+
        | Master 节点 |         | Backup 节点 |
        |   持有 VIP  |         |   待命状态  |
        +-------------+         +-------------+
              |                          |
      心跳同步 | <------ VRRP --------> | 心跳同步
              |                          |
  • Master 节点:拥有 VIP,对外提供服务。
  • Backup 节点:等待状态,定期发送/接收 VRRP 心跳。
  • VIP 自动漂移:Master 挂了 → Backup 无心跳 → 自动接管 VIP。

3.2 VIP 漂移原理(VRRP)

  • 每个节点都有一个 优先级(priority)
  • Keepalived 周期性发送 VRRP 心跳广告(advert_int 时间间隔)
  • Backup 节点若超过一定时间未收到主节点的 VRRP 广播,就认为主已失效,触发 VIP 漂移。

四、实际部署步骤

4.1 安装 Keepalived(CentOS 为例)

yum install -y keepalived

4.2 配置文件路径

/etc/keepalived/keepalived.conf

4.3 主节点配置(示例)

vrrp_instance VI_1 {
    state MASTER
    interface ens33                # 网卡名(用 ifconfig 查看)
    virtual_router_id 51          # 同一个 VRRP 实例编号,主备必须一致
    priority 100                  # 优先级(Master 优先级 > Backup)
    advert_int 1                  # 心跳间隔(秒)

    authentication {
        auth_type PASS
        auth_pass 123456
    }

    virtual_ipaddress {
        192.168.1.100              # 虚拟 IP
    }
}

4.4 备节点配置(与主基本一致)

state BACKUP
priority 90

确保 virtual_router_idauth_pass 完全一致!


五、Keepalived 健康检查机制

问题:Keepalived 是活的,但服务(如 Nginx)挂了怎么办?

解决方案:编写健康检查脚本

5.1 脚本内容 /etc/keepalived/check_nginx.sh

#!/bin/bash

# 方式一:判断端口(不依赖 curl)
if ! ss -lntp | grep ':80' > /dev/null; then
    pkill keepalived
fi

# 方式二:通过 curl 检查 HTTP 状态码
# curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1 | grep -q "200" || pkill keepalived

5.2 引入脚本配置

vrrp_script check_nginx {
    script "/etc/keepalived/check_nginx.sh"
    interval 2         # 每 2 秒检测一次
    weight -20         # 若失败则降低优先级
}

vrrp_instance VI_1 {
    ...
    track_script {
        check_nginx
    }
}

六、互为主备 + 双 VIP 架构(资源最大化)

在默认主备模式下,Backup 节点处于“吃干饭”状态。为提高资源利用率,可采用:

6.1 双 VIP + 互为主备设计

主机A 主机B
VIP1 VIP2
Master(VIP1) Backup(VIP1)
Backup(VIP2) Master(VIP2)

6.2 DNS 轮询实现双活负载

www.example.com 同时解析到 VIP1 和 VIP2:

www.example.com → 192.168.1.100
www.example.com → 192.168.1.101

用户请求将随机访问其中一台,实现简单的DNS 负载均衡


七、防止抢占与频繁漂移

7.1 抢占问题

默认情况下:

  • Master 宕机 → Backup 接管 VIP
  • Master 恢复后 → 会重新抢回 VIP

缺点: VIP 再次漂移,可能造成短暂闪断或状态错乱

7.2 解决方案:禁用抢占

nopreempt

加在 vrrp_instance 内,代表:

即使原 Master 恢复,也不再抢回 VIP,直到 Backup 也失效。


八、脑裂(Split Brain)问题详解

8.1 什么是脑裂?

两台主机同时认为对方已宕机,并同时接管 VIP,变成双主。

8.2 导致原因

  • VRRP 心跳包丢失(网络中断、心跳端口异常)
  • 配置错误(相同优先级、误抢占)
  • 杀死 keepalived 进程未释放 VIP

8.3 后果

  • 双节点抢占 VIP,客户端请求乱序
  • 数据不一致、丢失、服务不稳定

8.4 防护策略

策略 说明
正确关闭 使用 systemctl stop keepalived 而非 kill -9
自动释放 IP 在脚本中加入 IP 清理命令
网络冗余 使用双网卡、心跳多链路
优化探测机制 增加健康检查可靠性(ping + curl)
配置惩罚机制 探测失败就 pkill + ip addr del,主动退出竞选

九、典型故障场景模拟

故障类型 影响 解决措施
Nginx 挂了 VIP 未漂移,服务断开 健康检查脚本,结合 curl 检查 HTTP 状态码
Keepalived 挂了 VIP 仍在本机,未释放 使用 systemctl 正确停止
主机掉电 Backup 接管 VIP,服务不中断 检查是否设置了 nopreempt 防止频繁漂移
心跳丢包 脑裂,双主接管 VIP 优化网络链路、启用双心跳

十、总结与最佳实践

要点 建议
节点角色 主备分明,优先级配置合理
健康检查 脚本必须能真实检测服务状态
非抢占策略 推荐开启 nopreempt,避免频繁漂移
测试环境 尽量模拟各种故障,验证 HA 效果
互为主备 可提升资源利用率,但增加配置复杂度
脑裂防护 网络、脚本、优先级等多层防线并举

你可能感兴趣的:(nginx,运维,分布式,架构,java)