服务器高可用方案有哪些

结论:服务器高可用方案从低到高分为六档:单机 + 定期备份、主从复制(Primary/Standby)、双机热备(Keepalived + VIP)、共享存储(DRBD)、数据库高可用组(MGR/Patroni)、异地多活。中小企业最划算的选择通常是"双机 + Keepalived VIP + 数据库主从",能以较低成本达到 99.9% 可用性。

服务器高可用(High Availability,HA)解决的是一个朴素的问题:机器一定会坏,那坏了之后业务要停多久。讨论 HA 前必须先把两个指标说清楚——RTO(Recovery Time Objective,恢复时间目标)指"故障后允许多久恢复服务",RPO(Recovery Point Objective,恢复点目标)指"故障后允许丢失多少数据"。这两个数字决定了方案的天花板:要求 RPO=0(零数据丢失),就必须做同步复制;要求 RTO<30 秒,就必须有自动故障转移(Failover),人工介入是绝对来不及的。

为什么单机永远谈不上高可用?

因为单台服务器存在无法消除的单点故障(SPOF,Single Point of Failure)。即使你给这台机器配了双电源、RAID 10 磁盘阵列、双网卡绑定,操作系统崩溃、机房断电、交换机故障、误操作执行了 rm -rf,任何一个都能让业务彻底中断。高可用做的不是"让机器不坏",而是"让单点不再是单点"。

衡量可用性用"几个 9"表示,对应的年度停机时间如下:

可用性等级年停机时间月停机时间典型架构
99%(两个 9)约 87.6 小时约 7.3 小时单机 + 手工恢复
99.9%(三个 9)约 8.76 小时约 43.8 分钟双机热备 + 自动切换
99.99%(四个 9)约 52.6 分钟约 4.4 分钟多节点集群 + 自动编排
99.999%(五个 9)约 5.26 分钟约 26 秒异地多活 + 混沌工程验证

六种主流高可用方案对比怎么选?

选型的核心原则是:先消除最贵、最容易坏的那个单点,通常是数据库。应用层做无状态化之后横向扩多个节点非常便宜,而数据库的有状态特性决定了它是 HA 架构里最难啃、成本最高的部分。

方案可用性等级RTORPO成本适用场景
单机 + 定时备份99%数小时上次备份点(可能丢一天)低个人站、内部工具、可容忍长时间中断
应用层多节点 + Nginx 负载均衡99.9%秒级0低无状态 Web 服务,最推荐的起步方案
主从复制(Primary/Standby)99.9%5~30 分钟(半自动)异步复制可能有秒级丢失中数据库读多写少,允许短暂降级
Keepalived + VIP 双机热备99.9%1~3 秒取决于后端数据同步方式中网关、Nginx、Redis 等无状态/半状态服务
DRBD + Pacemaker99.99%5~10 秒接近 0(同步复制)高要求强一致又不愿上共享存储的两节点场景
MySQL MGR / Patroni + etcd99.99%10~30 秒0(多数派确认)高金融、交易、订单等核心业务库
异地多活(Cell/Unit 化)99.999%秒级0(单元内自洽)极高大型互联网业务,容机房级故障

Keepalived + VIP 双机热备怎么配置?

Keepalived 通过 VRRP(Virtual Router Redundancy Protocol,虚拟路由冗余协议)在多台机器之间共同持有一个虚拟 IP(VIP,Virtual IP),主节点正常工作时 VIP 落在它身上,主节点宕机后备节点在 1~3 秒内接管 VIP,客户端全程只访问这个 VIP,因此无需修改任何 DNS 或客户端配置。

典型的双节点拓扑:节点 A 10.0.0.11(MASTER,priority 150)、节点 B 10.0.0.12(BACKUP,priority 100)、虚拟 IP 10.0.0.100。

在主节点上的配置文件 /etc/keepalived/keepalived.conf:

conf
! Configuration File for keepalived
global_defs {
    router_id HA_NODE_01
    script_user root
    enable_script_security
}

# 健康检查脚本:检测本机 Nginx 是否存活
vrrp_script chk_nginx {
    script "/etc/keepalived/check_nginx.sh"
    interval 2
    timeout 2
    weight -30
    fall 2
    rise 1
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 150
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass Ha@2026Secret
    }

    virtual_ipaddress {
        10.0.0.100/24 dev eth0 label eth0:1
    }

    track_script {
        chk_nginx
    }

    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault  "/etc/keepalived/notify.sh fault"
}

备节点的配置只需改三处:router_id 改为 HA_NODE_02、state 改为 BACKUP、priority 改为 100。

配套的 Nginx 健康检查脚本示例:

bash
#!/bin/bash
# /etc/keepalived/check_nginx.sh —— 返回 0 表示健康,非 0 表示异常
if pidof nginx > /dev/null 2>&1; then
    if curl -sf -o /dev/null -m 2 http://127.0.0.1/healthz; then
        exit 0
    fi
fi
exit 1

启动与验证:

bash
chmod 700 /etc/keepalived/check_nginx.sh
systemctl enable --now keepalived

# 在主节点查看 VIP 是否成功挂载到 eth0
ip addr show eth0 | grep "10.0.0.100"

# 模拟故障:停掉主节点 Nginx,观察 VIP 是否在数秒内漂移到备节点
systemctl stop nginx && sleep 5 && ip addr show eth0 | grep "10.0.0.100"

# 查看 VRRP 日志确认切换过程
journalctl -u keepalived -f

关键要点:VIP 必须与管理网/业务网在同一二层网段内,因此 Keepalived 通常只能在同一个 VPC 或同一个机房内使用,跨地域需要改用云厂商的 Anycast EIP 或全局负载均衡。

有状态的数据库怎么做高可用?

数据库高可用的本质是"副本 + 一致性协议 + 自动选主"。截至 2026 年,MySQL 生态最主流的有三条路线:MySQL Group Replication(MGR,官方方案,8.0 起成熟)、Patroni + etcd(PostgreSQL 的事实标准,也支持 MySQL)、以及云厂商托管的高可用版 RDS(最省心,底层通常也是类似机制)。

MGR 的核心优势是"多数派确认":一个事务必须在超过半数节点(如 3 节点中的 2 个)写入成功后才返回客户端成功,因此能做到 RPO=0。它的最小可行部署是 3 节点(2 节点无法形成多数派,任何一台宕机后整体不可写)。

ini
# MySQL 8.4 单主模式 MGR 关键配置片段(/etc/mysql/conf.d/mgr.cnf)
[mysqld]
server_id = 1                        # 三节点分别为 1、2、3,必须唯一
gtid_mode = ON
enforce_gtid_consistency = ON
binlog_format = ROW
binlog_checksum = NONE               # MGR 要求关闭 binlog 校验
transaction_write_set_extraction = XXHASH64
loose-group_replication_group_name = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
loose-group_replication_start_on_boot = OFF
loose-group_replication_local_address = "10.0.0.11:33061"
loose-group_replication_group_seeds  = "10.0.0.11:33061,10.0.0.12:33061,10.0.0.13:33061"
loose-group_replication_bootstrap_group = OFF
loose-group_replication_single_primary_mode = ON
loose-group_replication_enforce_update_everywhere_checks = OFF

启动集群并检查成员状态:

sql
-- 在第一个节点上引导集群(仅执行一次)
SET GLOBAL group_replication_bootstrap_group = ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group = OFF;

-- 在其余节点上加入集群
START GROUP_REPLICATION;

-- 查看成员状态,MEMBER_STATE 应为 ONLINE
SELECT MEMBER_HOST, MEMBER_PORT, MEMBER_STATE, MEMBER_ROLE
FROM performance_schema.replication_group_members;

应用要想自动跟随主库切换,还需在前面加一层代理。MySQL Router 会自动读取 MGR 的拓扑并重写连接路由;更灵活的选择是 ProxySQL + Consul 的服务发现方案。

无状态化设计为什么是高可用的前提?

因为只有把状态从应用进程里剥离出去,横向扩容和故障切换才能做到秒级且无副作用。所谓无状态,就是任何一个请求落到哪台机器上都能得到相同结果——Session 存 Redis 而不是本机文件、上传的图片存对象存储而不是本地磁盘、定时任务用分布式锁保证只有一个节点执行。

落地的三条硬规则:

  • Session 外置:配置 PHP/Java/Node 的 Session 存储到 Redis 集群,绝不用本地文件或进程内存。
  • 文件外置:用户上传内容一律写入对象存储(OSS/COS/S3)或共享文件系统(NFS/CephFS),并通过 CDN 分发。
  • 配置中心化:数据库连接串、密钥等放到环境变量或配置中心,避免各节点配置漂移。

做完无状态改造后,应用层可以随意扩到 2 台、10 台,任何一台宕机,负载均衡的健康检查会在 5~10 秒内把它摘除,用户毫无感知。

常见误区 / 排错提示

  • 误区一:以为两台机器就是高可用。 两台机器共用一台交换机、一个机柜、一路供电,那个"共用的东西"就是新的单点。真正的高可用要求冗余路径处处可能分裂:双机在不同可用区、接不同交换机、走不同运营商链路。
  • 误区二:没做脑裂(Split-Brain)防护。 Keepalived 两节点之间心跳中断但双方都活着时,两边都会抢着挂 VIP,造成双写数据损坏。解决办法是配置 nopreempt(非抢占)+ 至少三条心跳链路,存储层面用 STONITH/fence 机制直接隔离故障节点。
  • 误区三:只搭了架构却从没演练过。 未经演练的高可用等于没有高可用。必须每季度做一次真实的故障注入演练(直接 reboot 主库),验证 RTO 是否真的达标,并更新运维手册。
  • 误区四:忽略备份。 高可用防的是硬件故障与单点失效,防不住误删数据和勒索软件。误操作会同步复制到所有副本。因此 HA 之外必须有独立的、异地的时间点备份。
  • 排错:Keepalived 启动后 VIP 不生效。 常见原因是云平台不允许随意绑定非本机的 IP。阿里云、腾讯云等公有云需要为实例绑定"高可用虚拟 IP(HAVIP)"并把 VIP 加入该实例的可绑定列表,否则 ARP 通告会被云平台的安全策略丢弃。
  • 排错:VIP 频繁抖动漂移。 检查 vrrp_script 的 interval 是否过小、fall 次数是否太少,网络轻微抖动就会误判。建议 interval 不小于 2 秒、fall 设为 2~3。

常见问题(FAQ)

中小企业预算有限,该怎么选高可用方案?

结论:优先做"应用层双节点 + 负载均衡 + 数据库主从 + 每日异地备份"这套组合,成本增量约一倍的服务器费用。这套架构能达到 99.9% 左右可用性,覆盖了绝大多数中小企业场景。真正的省钱技巧是先做无状态化改造和数据外置,这样后续扩容只需加廉价的计算节点,而不是给数据库不断堆配置。

高可用方案和备份有什么区别?能互相替代吗?

结论:不能互相替代,二者防的是完全不同的风险。高可用防的是"硬件坏了服务能不能立刻继续",追求 RTO 最小化;备份防的是"数据被误删或加密了能不能拿回来",追求的是历史时间点可恢复。高可用架构里的删库 Operate 会一路复制到所有副本,此时唯一能救命的就是备份。

两个节点能不能做 MySQL MGR 或 etcd?

结论:不推荐,两节点无法形成多数派,反而降低可用性。三节点 quorum 集群能容忍 1 个节点失效;而两节点集群任何一方宕机后,剩下的一台会因拿不到多数票而变为只读甚至整体不可用。如果预算确实只够两台,可以加一个只参与投票不承担数据的仲裁节点(Arbiter/GARB),成本极低。

Keepalived 高可用在公有云上能用吗?

结论:能用,但必须使用云平台提供的 HAVIP 能力,标准 VRRP 组播通常不通。多数公有云的 VPC 网络不支持自定义 ARP 广播和 VRRP 组播,直接跑 Keepalived 会出现双节点都挂 VIP 或都挂不上的怪现象。替代方案是直接使用云厂商的 SLB/CLB 做健康检查与流量切换,比自建更稳。

什么是脑裂?怎么避免?

结论:脑裂是指集群心跳断开后,两边节点都认为自己该继续服务,导致同时对共享资源写入而损坏数据。避免手段有三层:网络层用多条独立心跳链路(至少 3 条,或心跳走独立交换机);协议层使用奇数节点的 quorum 多数派投票;硬件层配置 fencing/STONITH,一旦发现节点失联就直接把它断电或隔离。

RTO 和 RPO 该怎么定才合理?

结论:不要用拍脑袋的数字,用业务损失金额倒推。先算出一小时停机造成的直接营收损失与合规风险,再和方案成本做对比:如果某业务停机 1 小时损失 10 万元,而把 RTO 从 30 分钟压到 1 分钟要多花 50 万元每年,那么 30 分钟的 RTO 就是更理性的选择。一般建议:核心交易类 RTO<5 分钟、RPO=0;内容展示类 RTO<1 小时、RPO<15 分钟即可。