服务器异地多活容灾架构搭建:零基础完整教程
为什么需要异地多活容灾架构
如果你的网站或业务只有一台服务器,
一旦机房停电、
光纤被挖断或服务器硬件故障,
整个服务就会挂掉。服务器异地多活容灾架构就是让多台分布在异地机房的服务器同时提供服务,
任何一台或一个机房出问题,
流量自动切到其他节点,
用户几乎无感知。
本文以最简方案为例——两台服务器(分别放在阿里云和腾讯云的不同地域)、
一个域名、
MySQL 做主主同步 + Nginx 作反向代理 + Keepalived 实现 VIP 漂移,
带你一步步搭建起来。
前置准备:你需要什么
- 两台云服务器:系统建议 CentOS 7.9+ 或 Ubuntu 20.04+,开启 22、3306、80、443 端口。
- 一个已备案的域名:用于 DNS 智能解析,做到线路就近访问。
- 基础环境:两台机器都装好 Nginx、MySQL、Keepalived,并确保能互相 ping 通(建议内网或专线,如果没有则使用公网 IP 并配好安全组)。
- 时间同步:两台服务器都安装
ntpdate并同步到同一个 NTP 服务器,避免数据冲突。
分步搭建异地多活架构
1. 配置 MySQL 主主同步
主主同步(也称双向同步)能让两台服务器上的数据库实时保持一致。
假设A机房服务器IP为 192.168.1.10,B机房为 192.168.1.20。
第一步:在两台机器上修改 MySQL 配置文件 /etc/my.cnf(或 /etc/mysql/my.cnf),在 [mysqld] 段下添加:
# A 机房配置
server-id = 1
log-bin = mysql-bin
binlog-do-db = your_db # 要同步的数据库名
replicate-do-db = your_db
auto-increment-increment = 2
auto-increment-offset = 1
# B 机房配置
server-id = 2
log-bin = mysql-bin
binlog-do-db = your_db
replicate-do-db = your_db
auto-increment-increment = 2
auto-increment-offset = 2
auto-increment-increment 和 auto-increment-offset 能避免主键冲突(A库生成奇数ID,B库生成偶数ID)。
第二步:重启 MySQL 并创建同步用户。
systemctl restart mysqld
mysql -u root -p
在A机执行:
CREATE USER 'sync'@'192.168.1.20' IDENTIFIED BY 'strong_password';
GRANT REPLICATION SLAVE ON *.* TO 'sync'@'192.168.1.20';
FLUSH PRIVILEGES;
SHOW MASTER STATUS; -- 记下 File 和 Position
在B机同样创建用户并记录 master 状态。
第三步:让A和B互为主从。
在A机执行:
CHANGE MASTER TO
MASTER_HOST='192.168.1.20',
MASTER_USER='sync',
MASTER_PASSWORD='strong_password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=xxx; -- 填上一步看到的 Position
START SLAVE;
在B机执行同样的命令,指向A机。
验证:在两台机器上分别执行 SHOW SLAVE STATUS\G,看到 Slave_IO_Running: Yes 和 Slave_SQL_Running: Yes 即成功。
2. 配置 Nginx + Keepalived 实现 VIP 漂移
Keepalived 可以让两台 Nginx 共享一个虚拟IP(VIP),当主节点挂掉时,VIP 自动漂移到备用节点。
安装:
# CentOS
yum install -y keepalived nginx
# Ubuntu
apt install -y keepalived nginx
编辑 Keepalived 配置文件 /etc/keepalived/keepalived.conf。
主节点(A机)配置:
global_defs {
router_id LVS_DEVEL_A
}
vrrp_script chk_nginx {
script "/usr/bin/killall -0 nginx" # 检查nginx进程
interval 2
weight -20
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.1.100/24 # VIP
}
track_script {
chk_nginx
}
}
备节点(B机)配置:将 state MASTER 改为 state BACKUP,priority 设为 90,其他相同。
启动服务:
systemctl enable keepalived nginx
systemctl start keepalived
此时 VIP 192.168.1.100 会绑定在A机。
用 ip a 确认。
3. 配置 DNS 智能解析
在域名控制台添加两条A记录:
- 线路选择“默认”,值填A机公网IP(或VIP)。
- 再添加一条“电信/联通/移动”线路指向B机。
这样用户会就近访问,同时任意机房故障时通过健康监测自动切换DNS(需配合云服务商的健康检查,或使用自建脚本)。
避坑指南:新手最容易犯的错
- 数据冲突:主主同步中如果两边同时修改同一条记录且ID相同,会导致同步报错。一定要设置
auto-increment-increment和auto-increment-offset,并且业务代码中尽量避免并发写同一条。 - 防火墙与安全组:确保两台服务器之间的 3306 端口互通;Keepalived 依赖 VRRP 协议(IP 协议号 112),部分云平台需要额外开启。
- DNS 缓存:切换 DNS 记录后,客户端可能长时间被缓存劫持。建议将 TTL 调低(如 60 秒),并在故障时手动清空本地 DNS 缓存。
- 脑裂:Keepalived 通信中断时可能两台机器都认为自己是 MASTER,导致 VIP 冲突。解法:增加冗余心跳线路(如同时用 eth0 和 eth1),并配置
nopreempt模式。 - 注意 MySQL 同步延迟:异地机房之间的网络延迟会造成几十毫秒的数据滞后。写操作尽量只在主节点(如A机)进行,读操作分散到各节点。
效果验证:模拟故障看看是否容灾
验证步骤:
- 在A机用
systemctl stop nginx停掉 Nginx。 - 观察 Keepalived 日志:
tail -f /var/log/messages,应该看到 VIP 漂移到B机。 - 用外部设备访问域名或 VIP,看是否能正常打开网站。
- 在B机上创建一个测试表并插入一条数据,然后在A机上查询,确认数据已同步。
- 恢复A机 Nginx 服务,查看 VIP 是否会切换回来(取决于配置中的优先级和 nopreempt)。
更极端地,直接关闭A机实例,验证B机能否独立承担全部流量,且数据库写入正常。
总结
服务器异地多活容灾架构搭建并不神秘,核心就是“多地部署 + 数据同步 + 流量调度”。
本文演示了使用 MySQL 主主同步 + Nginx + Keepalived + DNS 智能解析实现一个四层保护的高可用方案。
虽然生产环境还需要考虑更多细节(如缓存同步、会话保持、自动故障恢复等),但掌握这套基础原理后,你完全可以在此基础上扩展出更适合自己业务的容灾体系。
如果你在搭建过程中遇到报错,优先检查防火墙、复制状态和配置文件语法,这能解决80%的问题。