作者简介
sh, 携程软件技术专家,关注性能优化、技术架构等领域。
团队热招岗位:软件技术专家
导读:本文来自携程刚刚上市的《全球化技术架构与实战》一书。携程集团自2016年起启动全球化战略,在全球化进程中,技术团队在挑战中学习,在磨砺中成长,积累了许多值得借鉴的经验。
全书以“全球化业务落地”为主线,深入剖析了从架构设计、流量调度、数据合规、基础设施,到体验优化、支付建设、客服系统及IT运维的完整技术实践,希望帮助出海企业规避技术陷阱,助力业务在海外平稳落地。
本月起,我们将推出4篇出海主题系列文章,带大家一起抢先看看新书中的部分精华内容。

一、引言
二、全球化带来的挑战
2.1 来自OTA业务场景的挑战
2.2 来自数据合规的挑战
2.3 可用性与稳定性
三、设计思路
3.1 用户体验与系统稳定性 - 全球多Region
3.1 数据合规 - 全球多合规区
四、整体方案
一、引言
全球化部署过程中,业务将面临一系列新的挑战。物理距离造成的网络延迟、复杂的部署结构带来的稳定性问题以及全球各地区对数据合规要求的差异都将为现有软件架构带来新的变量。考虑到携程的规模庞大、团队众多以及软件产品繁杂,我们迫切需要一个统一且完善的全球化解决方案。本文将围绕这一主题展开介绍。
二、全球化带来的挑战
在全球化的大背景下,软件架构也迎来不同挑战,其中来自OTA业务场景、数据合规、可用与稳定这三个方面的挑战最为突出。下面将详细阐述这三个方面的挑战。
2.1 来自OTA业务场景的挑战
为了让讲解更清晰,这里以在线旅游业务为例。为了确保用户无论身处何地都能享受到高质量的在线旅游服务,最直接的方案就是在每个地区部署数据中心,做到每个用户都有一个物理距离上相对接近的服务节点,以规避物理距离带来的网络延迟与不稳定性,如图1所示。用户就近访问服务节点,延迟低、响应快,体验自然提升。

图1 多数据中心就近访问示意图
在线旅游(OTA)业务场景下,用户通常是移动的。许多业务场景会涉及到跨地区操作。例如,用户a住在海外地区1,要去海外地区2旅游,在OTA App上安排了相应的行程。在用户到达地区2后,为了让用户在地区2依然享受到低延迟体验,还是要让用户就近访问地区2的数据中心,以尽可能规避跨地区网络延迟,如图2所示。但是行程是用户在地区1安排的,地区2的服务如何知道用户之前的状态呢?这里就引出了数据同步的问题:如何保证多个数据中心的数据一致性?在特定情况下,我们会需要一套强大可靠的数据复制组件来做到这一点。

图2 用户跨地区操作示意图
虽然保证多个数据中心的数据一致性已具有一定复杂度,但全球数据合规要求带来了更大的挑战。
2.2 来自数据合规的挑战
通常来说,用户数据(如账号、订单等)需要做到仅在法规允许的地区存储和处理,这显著增加了数据存储与流量控制的复杂性。为了描述这种复杂性,我们引入合规区的概念。合规区的划分以各国现行法律法规为基础,同时需要将地缘政治博弈格局、数据跨境合规动态演变、基础设施区位布局及技术实施成本等多维度要素纳入考虑,形成兼具合规性与商业效率的治理框架。我们希望通过合规区来清晰直观地表达全球数据部署的逻辑布局,方便我们快速定位各个地区用户数据的移动边界,如图3所示。

图3 合规区示意图
数据合规面临的最大挑战在于:局部隔离性与OTA业务的全局性之间存在天然矛盾。
首先,对于用户数据,我们需要设计一种机制来标定用户的归属地,并确保他们的数据只在对应的合规区落地。当用户身处其他合规区发起访问时,系统需要识别区分用户,通过某种方式找到用户数据所在的合规区,将该用户所有请求都重定向回对应合规区进行处理,如图4所示。

图4 用户合规访问示意图
所以,为了让系统能够区分不同合规区的用户,并找到相关的用户数据位置,我们需要设计一套覆盖全链路的统一染色方案,在手机端、接入层、应用层、控制层、数据层等环节对数据进行标记,从而使得系统可以将用户的合规区信息不断传递,如图5所示。这样才能确保:在业务生命周期的任意环节,系统总能知道当前数据应该存在哪,也能知道当前服务的用户属于哪个合规区。

图5 请求链路示意图
接着,我们还需要制定一套可拓展性极强的调度策略,并构建一个总控组件去完成流量转发的工作。这些工作包括但不限于:将合规区翻译成具体的网关地址、流量比例的控制、流量切换能力、请求失败时的应对策略。而消息、任务调度也要响应总控组件的指令,共同完成用户的跨区域业务。这也意味着,这个控制组件必须具备极强的可靠性和可拓展性,是众多基础组件的底层依赖,如图6所示。

图6 总控组件控制示意图
2.3 可用性与稳定性
最后,业务的可用性和稳定性也是我们需要考虑的核心因素。我们必须应对诸如机房火灾、断电等意外情况。所以,最好让合规区内的多个数据中心互为备份。当一个数据中心发生故障时,我们可以借由总控组件的切换能力,通过修改路由策略,将用户的流量路由到同合规区内就近的另一个数据中心,如图7所示。

图7 合规区内故障切换示意图
根据上述分析,我们制定了统一且完善的全球化解决方案。后续内容将进一步阐述该方案的核心内容,并展示其在实际业务场景中的具体应用。
三、设计思路
技术基础设施的部署架构通常包含以下两个主要层级:
Region (区域):Region 是根据地理位置划分的隔离区域,通常是全球化架构中的基本部署单元。一个 Region 内通常包含多个可用区 (Availability Zones, AZs),这些可用区通过低延迟网络互联。而不同的 Region 之间则是隔离的,互不影响。Region 间的通信链路质量存在延迟高、不稳定的特点。
AZ (Availability Zone,可用区): AZ是同一 Region 内进一步隔离的单元。每个 AZ 在电力、网络等物理设施上独立,但在同一 Region 内通过高速网络相互连接,以实现低延迟和高可用性。
Region 是全球化视角下的基本单元,后续介绍将基于 Region 级别展开,略去 Region 内多 AZ 架构的细节。
3.1 用户体验与系统稳定性 - 全球多 Region
虽然单 Region 是全球化架构的基本部署单元,但仅依赖单 Region 会存在明显弊端:
可用性:在复杂的全球化环境下,系统会面临区域间的网络故障,区域级的数据中心故障等场景。单 Region 架构无法很好地保障系统的稳定性。
用户体验:面对来自全球各地的用户,单 Region 无法保证所有的用户都能以较低的延迟接入,会极大影响服务的质量。
因此,全球化架构通常不会仅依赖单一Region进行部署。
此处以图8为例介绍单 Region 架构的典型组成 。

图8 单Region架构示意图
其中:
网关 (Gateway):承担了来自用户侧的第一跳流量,为用户请求与数据中心内的业务应用提供了标准、安全、高效的通信链路。
服务 (Service):业务应用通常由一系列功能内聚的服务组成,通过服务间的交互实现业务逻辑。
消息队列(MQ):消息队列提供了异步通信的能力,通过 Producer/Consumer 模型满足业务解耦需求。
缓存 (Cache):基于 Redis 的缓存在业界得到了广泛的使用,支撑了热点数据的高效访问。
数据库 (DB):基于 MySQL 提供了稳定可靠的数据库服务。
异步任务 (Job):部分业务逻辑依赖异步触发的调度任务执行,此类任务通常通过批量扫描与批量执行的模式对数据进行进一步的处理。
为了支撑全球化业务,多 Region 部署成为必然的选择。在简单的多 Region 架构下,用户就近访问临近的数据中心,可以获得更稳定、延迟更低的服务。在遇到 Region 级故障的时候,也可以将用户流量切换到其他 Region 的数据中心继续提供服务。简单的多 Region 架构如下图9所示。

图9 简单的多Region架构示意图
但是这样的架构还存在一定缺陷:用户数据只能在法律法规允许的地区进行处理,仅依赖就近访问的机制无法满足数据合规要求。因此不能采用简单的多 Region 架构,还需要进一步考虑数据合规带来的架构挑战。
3.2 数据合规 - 全球多合规区
“合规性优先”是全球化架构需要严格遵守的原则。数据的存储与使用需要严格遵循各个国家和地区的法律法规,所有的流量调度与应用处理逻辑都应该与底层数据相适配。为了更好的描述数据在全球化架构下的分布,需要再引入合规区(Compliance Area)的定义。
3.2.1 合规区(Compliance Area)
通常一个合规区包含多个 Region,这些 Region 都能满足数据合规带来的要求。在同一个合规区内,数据可以合法、合规地存储和使用;不同的合规区之间,数据则被严格隔离。
为了满足合规要求,数据分布必须遵循在合规区内封闭的原则,杜绝非法跨合规区的流动。基于合规原则,不同 Region 的数据中心会被划分到不同的逻辑合规区中,用户的数据仅能在该用户所属的合规区内被处理。图10所示是合规区的概念示意。

图10 合规区概念示意图
用户在进行全球旅行时,请求最初可能会优先连接到就近的数据中心网络接入点。为了严格保证数据合规,用户流量需要在接入点网关被进一步转发到对应的合规区内进行处理。为了实现这个目的,需要引入图11所示的组件。
UCS (Universal Control Service,全球化流量调度的总控组件):作为全球化应用架构的“大脑”,UCS 为应用的跨区域部署与流量的合规调度提供决策依据。UCS 提供了一套标准的流量调度模型与 SDK,各基础组件通过与 UCS SDK 的结合,为应用提供了透明、统一的全球流量调度能力。
虫洞:跨Region传输的标准链路。为了保证用户的请求能够高效地到达数据中心,接入层使用“就近接入”的策略;为了保证数据合规,用户请求需要被转发到特定的合规区内进行处理。为了支持全球转发的能力,需要引入虫洞组件。虫洞在复杂的全球网络链路基础上,提供了安全、稳定、高效的跨区域传输链路。

图11 虫洞与UCS示意图
同一个合规区内通常会有多个 Region,Region 间的通信链路存在延迟高、不稳定的特点,通常情况下每个 Region 需要具备独立承载数据读写的能力。在合规区内采用如图12所示的简单多 Region 架构会有一定的缺陷:假如遇到单 Region 故障,用户的请求会被路由到同合规区内的其他可用 Region 进行处理,但是此时 Region 内没有该用户相关的数据,无法完成相关的业务处理。

图12 简单的多 Region 架构示意图
为了保障可用性,数据需要在不同的 Region 间复制备份来支持故障时的流量切换。为了更好地应对多 Region 复杂环境带来的挑战,针对不同类型的数据分别引入对应的数据同步组件,如图13所示。
DRC: 提供了高效可靠的跨区域 MySQL 双向同步能力
X-Pipe: 提供了高效可靠的跨区域 Redis 双向同步能力
MQ-Mirror: 提供了高效可靠的跨区域消息同步能力

图13 数据复制组件示意图
3.2.2 用户数据合规归属地(UDL)
在遵循合规区内严格封闭的前提下,不同类型的数据通过跨 Region 的数据同步组件在 Region 间同步备份来保障可用性。在引入数据的多活架构后,就需要考虑数据冲突的问题。在常见的软件架构下,除了实时请求的处理,还会存在一部分异步处理流程。比如,基于消息订阅或定时扫描触发的业务数据处理流程。
a. 初始状态下,用户 X 在 Region 12 发起请求;Region 12 内部署了一个定时任务,每隔一定时间扫描增量数据,在进行处理后写回数据库
b. 用户 X 移动到 Region 11 覆盖的区域,这时候 X 发起的请求会接入 Region 11 并在 Region 11 完成数据更新操作
c. 此时到了 Region 12 的定时任务触发时间:Region 12 的任务扫描到用户 X 的历史数据变更,执行了处理逻辑并将结果写回 Region 12 的数据库中
d. Region 间的数据同步天然存在一定的延迟,此时在两个 Region 内都对用户 X 的进行数据操作,可能会产生数据冲突。
针对核心的用户数据(如用户账号、订单等)等需要严格保证数据一致性的场景,为了避免数据冲突,最高效可靠的方式是:从源头就避免冲突,借助流量层的调度能力,确保同一个用户的数据在同一个 Region 内处理。
作为全球化架构的“大脑”,UCS 需要解决合规要求与数据一致性要求对流量调度带来的挑战。如何确定一个用户的数据应该在哪里被处理呢?很自然地可以联想到,需要设计一个标识,通过这个标识在用户与可以合法处理该用户数据的Region之间建立路由规则。在 UCS 体系内,这个标识被称为用户数据合规归属地(User Data Location,UDL)。
UDL是一个逻辑的概念,并不直接与物理部署相绑定;具有相同的 UDL 的账号遵循相同的法律法规,需要一致的行为。每个用户具有唯一确定的 UDL。关于 UDL 的定义下面做进一步展开思考。
(1)直接使用合规区作为 UDL是否可行?
答案是否定的。直接使用合规区作为 UDL 在面临调整的时候会存在一定的限制。考虑图14所示的场景:原先所有来自合规区-1的用户,都被标记为 UDL=CA-1;由于法规变动导致 CA-1 中的部分用户不再属于该合规区(将这部分用户称为 USER_GROUP_B)。为了满足合规要求,需要:
a. 从所有 UDL=CA-1 的用户中分析并筛选出所有属于 USER_GROUP_B 的用户b. 将对应用户的数据迁移到可以合法处理 USER_GROUP_B 用户的合规区(记为 CA-2)中
c. 将对应用户数据的 UDL 值更新为 CA-2。

图14 使用合规区作为UDL的场景示意图
所以,直接使用合规区作为 UDL 会导致系统在面临这样的场景时需要进行大批量的数据筛选与处理。
(2)使用 Region 作为 UDL 是否可行?
答案也是否定的。使用数据中心的 Region 值作为 UDL 也存在一定限制。考虑图15所示的场景:原先在 CA-1 内,部署了 Region_A、Region_B 两个数据中心。来自 USER_GROUP_C 的用户此时接入的是 Region_B 这个数据中心,其 UDL=Region_B。如果要在 CA-1 中新建一个 Region_C,需要:
a. 新建 Region_C,完成数据同步
b. 从所有 UDL=Region_B 的用户分中析并筛选出所有属于 USER_GROUP_C 的用户
c. 将对应用户数据的 UDL 值更新为 Region_C。

图2-15 使用Region作为UDL的场景示意图
所以,直接使用 Region 作为 UDL 会导致系统在面临这样的场景时也需要进行大批量的数据筛选与处理。
综合上述考虑,应该结合业务属性、用户各类属地标签,选择能更准确代表用户真实服务场景需求及具备较高稳定性的值作为UDL,以平衡商业可用性与用户隐私保护。
再回顾一下上述的场景。
合规区调整场景(见图16)为了将 USER_GROUP_B 用户迁移到新的合规区中,仅需要将所有 UDL=UDL_3 的数据迁移到合规区-2。

图16 依据UDL进行CA调整的场景示意图
新建 Region 场景(见图17)在合规区内新建 Region 时,仅需要新建 Region_C 并切换相关用户的流量调度规则。

图17 依据UDL进行Region迁移的场景示意图
(3)请求链路中 UDL 如何获取?
最朴素的想法是:每次需要 UDL 时候,都通过 UserID 查询用户的 UDL,如下图18所示。

图18 依赖中心化UDL服务的示意图
这个方式存在两个问题:
a. 每次调用时都增加了一次RPC调用,引入一个新的外部依赖和额外的RPC耗时,对系统稳定性和性能都有影响
b. UDL 查询服务将会成为一个超级单点服务,众多应用将依赖它,任何微小的变动都可能导致严重的损失
进一步思考,其实只要在网关层查询一次 UDL 并将其放入当前请求的全链路上下文中,这样后续所有服务需要 UDL 信息时,就可以直接从全链路上下文中获取,如图 19 所示。

图19 由Gateway依赖UDL查询服务的示意图
该方案虽然有效降低了各服务与 UDL 查询服务的耦合度,但并没有根本解决之前的两个问题。
a. 请求链路中依旧增加了一次RPC调用,会有稳定性和性能影响
b. 依然存在 UDL 查询服务这一单点依赖
再进一步思考,用户的 UDL 其实是一个相对稳定的元信息,可以在用户登录时随登录态一并下发到客户端上。UDL由客户端框架在请求中自动携带,并通过上述方式实现全链路传递,如下图 20 所示。

图20 登录时下发UDL的示意图
这个登录时下发 UDL 的方案既降低了请求链路上各个环节获取 UDL 的成本,也避免了额外引入 UDL 查询服务这一中心化依赖。
UDL 方案为全球合规部署提供了路由依据。此阶段的架构具备了以下特点:
用户数据在合规区内严格封闭
数据在合规区内的多 Region 间同步,支持多 Region 容灾
用户流量就近接入,提升请求可达率
基于 UDL 进行流量调度,保证用户数据的一致性与合规性
通过接入层网关与服务的流量调度能力,避免用户数据的多 Region 更新冲突
四、整体方案
前文的设计思考阐述了全球化背景下软件架构面临的核心挑战及应对方案。通过引入DRC、X-Pipe、MQ-Mirror等组件,实现跨Region数据同步,增强全球化架构的可用性;通过UCS流量调度与虫洞传输技术,确保用户数据处理的一致性。在数据合规方面,引入合规区概念,通过与 UDL 流量调度方案的结合,实现数据存储与处理的合法闭环。最终得到了如图 21 所示的全球化总体方案:

图21 全球化软件架构总体方案示意图
【有奖互动】你所在的企业在出海过程中,遇到过哪些技术挑战?欢迎在评论区留言,点赞最高的评论将获得新书一本,截止12月19日24点。

【推荐阅读】

“携程技术”公众号
分享,交流,成长

被折叠的 条评论
为什么被折叠?



