大家好!在当今这个对服务连续性要求极高的时代,系统的高可用性(High Availability, HA)已经不再是加分项,而是必备项。而“异地多活”架构,作为实现顶级高可用性的关键方案之一,经常被提及,但也常常让人觉得高深莫测,实施复杂。
很多人会觉得,只有像双十一那样的海量并发场景,或者金融支付那样对数据一致性要求苛刻的业务,才需要异地多活。而且,业务规模越大,设计起来是不是就越复杂?
其实,不一定!业务规模大,并不意味着异地多活架构就一定复杂。关键在于抓住核心,理解业务本质,并采用合适的策略。
今天,我们就通过两个大家耳熟能详的案例——王者荣耀和视频会议系统,来模拟实战一下异地多活架构的设计过程,看看如何通过一套结构化的方法,庖丁解牛般地拆解这个看似复杂的问题。
异地多活设计的通用“四步法”
在深入案例之前,我们先提炼一个通用的设计思路,可以概括为“四步法”:
- 业务分级 (Business Prioritization):
这是最关键的一步。明确哪些是你的核心业务,必须在任何情况下(包括单机房故障)都能保证运行?哪些业务可以接受短暂中断或降级?不是所有功能都需要异地多活,抓住核心才能避免过度设计。 - 数据分类 (Data Classification):
梳理核心业务依赖的数据。这些数据有哪些特性?是全局唯一的 ID?是状态会频繁变化的?是只增不改的流水?是允许丢失的临时数据?不同的数据特性决定了后续的同步和处理策略。 - 数据同步 (Data Synchronization):
根据数据的分类和业务需求,设计跨机房的数据同步方案。是需要强一致性还是最终一致性?是采用数据库同步、消息队列,还是特定算法生成(避免同步)?同步策略直接影响架构的复杂度和成本。 - 异常处理 (Exception Handling):
预先考虑各种异常情况,并制定应对预案。比如,数据同步延迟怎么办?依赖的第三方服务挂了怎么办?用户在操作过程中机房故障怎么办?是否可以接受一定程度的业务规则“放松”(如临时允许欠费)来保证核心流程?
掌握了这四个步骤,我们就可以开始实战演练了。
案例一:王者荣耀异地多活架构模拟设计
1. 背景速览
- 业务体量:
日活上亿,同时在线百万级。 - 核心功能:
登录、对战、商城、活动、社区等。 - 关键约束:
需登录才能对战;用户分“区服”,但可跨区对战。
2. 设计实战(应用四步法)
Step 1: 业务分级
- 核心业务:
登录和对战。这是玩家最基本的游戏体验,必须保证。 - 非核心业务:
注册(新用户暂时无法加入影响有限)、商城(短暂不可用,收入损失通常小于核心体验受损)、活动、社区等。思考:为什么直接影响收入的商城不是核心?因为对于游戏来说,保证玩家能“玩起来”是第一位的,购物体验中断通常比无法登录或对战的影响要小。 Step 2: 数据分类
- 登录相关:
依赖QQ/微信授权,王者本身只需记录 RoleID(全局唯一) 与区服的对应关系。这个关系数据只会新增,不会修改。 - 对战相关:
RoleID(不变)、对战ID(每次新建,全局唯一,生成后不变)、对战数据 (如过程、结果,与对战ID绑定,只会新建,不会修改)。 Step 3: 数据同步
RoleID与区服关系:只需简单的数据库同步即可。 RoleID全量同步。对战ID: 算法生成保证全局唯一,无需同步,或简单的数据库同步。 -
对战数据:与 对战ID绑定,简单的数据库同步。 -
其它用户数据(英雄、皮肤、等级等):按区服进行同步。 -
对战结果:采用主主同步 (Active-Active Sync),保证两个机房都能看到最新的结果。 - 核心发现:
王者荣耀的核心业务(登录、对战)产生的数据,大部分是只增不改 (Append-Only) 的!这大大简化了数据同步。 - 同步策略:
Step 4: 异常处理
- 依赖故障:
微信/QQ登录挂了?直接发公告停服维护。(强依赖,无法绕过) - 同步延迟:
新建小号信息未同步到异地机房?等系统恢复即可。对战结果未同步?等恢复了再看。 - 对战中断:
用户对战中机房故障?用户重新匹配即可,原有对战作废。 - 核心思考:
游戏业务,尤其是非竞技类或非关键性比赛,对于短暂的停服或数据延迟容忍度相对较高。
3. 架构示意
-
用户流量通过 DNS 路由到某个机房(如北方/南方)。 -
通过“归属地路由”判断用户的区服主要落在哪个机房。 -
区服服务器 (Zone Server) 处理常规用户数据,有主备关系(如 22 区主在南方,备在北方)。 -
对战服务器 (Battle Server) 处理对战逻辑,通常是主状态。 RoleID数据在机房之间全量同步。 -
区服相关的用户数据(英雄、皮肤等)按区服进行主备同步。 -
对战结果数据在对战服务器之间进行主主同步。
这个案例告诉我们,即使是亿级用户的系统,如果核心业务的数据模型简单(如 Append-Only),异地多活设计也可以相对简洁。
案例二:视频会议异地多活架构模拟设计
1. 背景速览
- 部署架构:
用户按地理位置分南方区(深圳机房)和北方区(天津机房)。 - 核心功能:
注册、登录、发起/加入会议、充值、用户管理等。 - 关键约束:
需登录参会;需充值(余额足够)才能发起会议。
2. 设计实战(应用四步法)
Step 1: 业务分级
- 核心业务:
登录、发起会议、加入会议。保证用户能开会是首要任务。 - 非核心业务:
注册(可通过邀请码等方式临时绕过)、充值(可考虑临时欠费)、用户资料修改等。思考:为什么余额不足不能开会,但充值却不是核心?因为“开会”这个动作本身是核心,而充值是前置条件。可以通过临时“放松”约束(允许欠费)来保障核心业务。 Step 2: 数据分类
- 登录相关:
用户ID(全局唯一,不变)、手机号(全局唯一,很少变)、Session ID(可丢失,重新生成)、密码(可能未及时同步,可丢失)。 - 发起会议相关:
用户ID、会议ID(全局唯一,算法生成,不变)、用户余额(全局强一致性要求)。 - 加入会议相关:
用户ID、会议ID。 Step 3: 数据同步
用户ID/ 手机号: 数据库同步 + 消息队列 保证可靠性。Session ID: 不同步,用户在异地机房需重新登录。 用户余额: 数据库同步。关键设计:充值操作只能在用户的“归属地”机房进行,避免双写冲突,简化一致性保障。 会议ID: 算法生成,无需同步。 Step 4: 异常处理
- 新用户注册未同步:
允许通过邀请码/链接等方式,不登录也能临时加入会议。 - 密码未同步导致异地登录失败:
提供多种登录方式(如手机验证码、绑定微信登录)。 - 异地发起会议时余额不足 (因充值只能在归属地):
业务上允许一定额度的欠费,保证会议能开起来。后续再进行结算。 - 会议中机房故障:
用户重新发起/加入会议。 - 核心思考:
视频会议(尤其是商业场景)对连续性要求高,可以通过牺牲部分非核心功能 (注册) 或临时放松业务约束 (允许欠费) 来换取核心业务(开会)的高可用。
3. 架构示意
-
DNS 路由 + 归属地路由。 -
用户服务器和会议服务器在两个机房互为备份(南方主/北方备,或反之)。 -
用户核心数据(ID、手机号、余额、会议记录等)在两个机房互为备份,通过数据库同步和消息队列保证。 -
开会结果等数据进行同步。
这个案例展示了当数据存在强一致性要求(如余额)时,可以通过限制写操作(归属地充值)和适当放松业务规则(允许欠费)来平衡可用性和一致性。

