导读:本文介绍了 Netflix 在 2022 年将其移动应用程序迁移到 GraphQL 的过程。他们采用了 AB 测试、Replay 测试和 Sticky Canaries 策略来确保安全地进行迁移。
在 2022 年,Netflix 的 iOS 和 Android 应用程序发生了重大变化。我们将 Netflix 的移动应用程序迁移到了 GraphQL,并实现了零停机时间,这涉及了从客户端到 API 层的全面改进。
直到最近,我们的移动应用程序使用的是内部 API 框架 Falcor。现在,它们使用了 Federated GraphQL,这是一种分布式的 API 方法,领域团队可以独立地管理和拥有特定部分的 API。
在不中断数亿用户的情况下安全地进行这项工作是极具挑战性的,特别是考虑到所涉及的众多变化维度。本博文将分享我们在进行这次迁移时使用的广泛适用的技术(超出了 GraphQL 范畴)。今天我们将讨论的三种策略是 AB 测试、Replay(回放)测试和 Sticky Canaries(金丝雀发布)。
迁移细节
在深入讨论这些技术之前,让我们简要了解一下迁移计划。
在使用 GraphQL 之前:API 团队实施和维护的单体式 Falcor API:
在迁移到 GraphQL 之前,我们的 API 层由使用 Falcor 构建的单体服务器组成。一个 API 团队同时维护 Falcor 框架的 Java 实现和 API 服务器。
阶段 1
在我们现有的单体 Falcor API 之上创建了一个 GraphQL Shim 服务。
到 2020 年夏季,许多 UI 工程师已准备好开始使用 GraphQL。我们没有选择从头到尾进行完整的迁移,而是在现有的 Falcor API 之上创建了一个 GraphQL shim。GraphQL shim 使得客户端工程师能够快速切换到 GraphQL,解决客户端方面的问题,如缓存规范化,尝试不同的 GraphQL 客户端,并在不受服务器端迁移的阻碍下研究客户端性能。为了安全地启动第一阶段,我们使用了 AB 测试。
阶段 2
废弃 GraphQL Shim 服务和传统 API 单体,转而采用由领域团队拥有的 GraphQL 服务。
我们不希望传统的 Falcor API 永远存在,因此我们采用了 Federated GraphQL 来支持一个具有多个 GraphQL 服务器的单一 GraphQL API。
我们还可以通过联合指令将 GraphQL Shim 的字段实现与 Video API 进行交换。为了安全地启动第二阶段,我们使用了 Replay 测试和 Sticky Canaries。
测试策略:概述
我们的测试策略受到两个关键因素的影响:
功能需求与非功能需求
幂等性
如果我们正在测试数据准确性等功能需求,并且请求是幂等的,我们会依靠 Replay 测试。我们知道我们可以使用相同的查询和相同的输入进行测试,并始终期望得到相同的结果。
对于请求非幂等字段的 GraphQL 查询或变更,我们无法进行 Replay 测试。
在非功能需求(如缓存和记录用户交互)的情况下,我们肯定无法进行 Replay 测试。在这种情况下,我们并不测试响应数据,而是整体行为。因此,我们依赖于基于更高层次指标的测试:AB 测试和 Sticky Canaries。
让我们详细讨论一下这三种测试策略。
工具:AB 测试
Netflix 传统上使用 AB 测试来评估新产品功能是否符合客户的需求。在第一阶段,我们利用 AB 测试框架将一个用户群体分为两组,总共 100 万用户。对照组的流量使用传统的 Falcor 堆栈,而实验组利用新的 GraphQL 客户端,并指向 GraphQL Shim。为了确定对客户的影响,我们可以比较各种指标,如错误率、延迟和渲染时间。
我们设置了一个客户端 AB 实验,测试 Falcor 与 GraphQL,并报告了粗粒度的用户体验指标(quality of experience metrics,QoE)。AB 实验结果表明,GraphQL 的正确性达不到遗留系统的水平。在
接下来的几个月,我们深入研究了这些高级指标,并修复了缓存 TTL、有缺陷的客户端假设等问题。
优势
高级健康指标:AB 测试为我们的整体客户端 GraphQL 实现提供了所需的保证。这帮助我们在 6 个月内成功将移动首页画布上 100% 的流量迁移到 GraphQL。
注意事项
错误诊断:通过 AB 测试,我们可以看到粗粒度的指标,指出潜在的问题,但很难诊断出具体问题。
工具: Replay 测试 - 大规模验证!
迁移的下一个阶段是在一个以 GraphQL 为主的服务器(Video API Service)中重新实现我们现有的 Falcor API。Falcor API 已经成为一个逻辑复杂的单体,积累了十多年的技术债务。因此,我们必须确保重新实现的 Video API 服务器没有错误,并且与已经产品化的 Shim 服务完全相同。
我们开发了一个 Replay 测试工具,以验证幂等的 API 是否从 GraphQL Shim 正确迁移到 Video API 服务中。
它是如何工作的?
Replay 测试框架利用 GraphQL 联合中提供的 @override 指令。该指令告诉 GraphQL 网关将请求路由到一个 GraphQL 服务器而不是另一个。例如,以下是 Shim 服务和 Video 服务定义的两个 GraphQL 模式:
在第一阶段,GraphQL Shim 首先定义了 certificationRating 字段(例如 Rated R 或 PG-13)。在第二阶段,我们建立了 VideoService,并定义了带有 @override 指令的相同 certificationRating 字段。具有 @override 指令的相同字段的存在告知 GraphQL 网关将此字段的解析路由到新的 Video Service,而不是旧的 Shim Service。
Replay 测试工具从 Mantis 中抽样原始流量。通过这些抽样事件,该工具可以捕获来自生产环境的实时请求,并对 GraphQL Shim 和新的 Video API 服务同时运行相同的 GraphQL 查询。然后,该工具比较结果并输出响应负载中的任何差异。
注意:我们不会对个人身份信息进行 Replay 测试。它仅用于 Netflix 用户界面上的非敏感产品功能。
测试完成后,工程师可以查看以展开的 JSON 节点形式显示的差异。你可以在逗号左侧的括号中看到对照值,而在右侧则是实验值。
我们在上述情况中捕获了两个差异,第一个差异是实验中缺少了一个 ID 字段的数据,第二个差异是编码不同。我们还注意到了本地化、日期精度和浮点数精度的差异。这让我们对复制的业务逻辑充满信心,其中订阅计划和用户地理位置确定了客户的目录可用性。
优势
对两种 GraphQL 实现之间的一致性充满信心。
在数据由于过于急切的超时而丢失的情况下,能够进行调优配置。
测试了需要许多(未知)输入和难以直观判断正确性的业务逻辑。
注意事项
不应使用 Replay 测试来测试包含个人身份信息(PII)和非幂等 API,因此有必要有一种机制来防止这种情况发生。
手动构建的查询只能测试开发人员记得测试的功能。由于遗忘,我们最终会有一些未经测试的字段。
正确性:正确性的概念也可能令人困惑。例如,对于一个数组来说,空数组更正确还是 null 更正确,或者只是噪音?最终,我们尽可能与现有行为保持一致,因为验证客户端错误处理的鲁棒性很困难。
尽管存在这些缺点, Replay 测试仍然是我们实现大多数幂等查询的功能正确性的关键指标。
工具:Sticky Canary
虽然 Replay 测试验证了新的 GraphQL API 的功能正确性,但它并不提供性能或业务指标的洞察,例如用户交互的整体感知健康状况。用户的点击率是否相同?加载是否及时,以免用户失去兴趣? Replay 测试也不能用于非幂等 API 的验证。为了增加信心,我们使用了 Netflix 的一种工具,称为 Sticky Canary。
Sticky Canary 是一种基础设施实验,其中在整个实验期间,客户分配给金丝雀或基线主机。所有传入的流量根据设备和配置文件分配给实验或基线主机,类似于桶哈希。实验主机部署为分配给实验的所有客户提供服务。您可以观看我们在亚马逊云科技 Reinvent 的混沌工程演讲,了解更多关于 Sticky Canary 的信息。
在我们的 GraphQL API 案例中,我们使用了 Sticky Canary 实验来运行两个 GraphQL 网关实例。基线网关使用现有的模式,将所有流量路由到 GraphQL Shim。实验网关使用新的提议模式,将流量路由到最新的 Video API 服务。我们的主要边缘网关 Zuul 根据实验参数将流量分配给两个集群之一。
然后,我们收集并分析两个集群的性能。我们密切监测的一些关键绩效指标包括:
中位数和尾部延迟
错误率
日志
资源利用率 - CPU、网络流量、内存、磁盘
设备 QoE(用户体验质量)指标
流媒体健康度指标
我们从小规模开始,将客户的分配量控制在一个小时的实验范围内。在验证性能后,我们逐渐扩大范围。我们增加了客户分配的百分比,引入了多区域测试,并最终进行了长达 12 小时甚至整天的实验。在整个过程中进行验证非常重要,因为 Sticky Canary 会对实际生产流量产生影响,并持续地分配给特定客户。
经过多次 Sticky Canary 实验,我们确信第二阶段的迁移改进了所有核心指标,可以放心地在全球范围内推广 GraphQL。
优势
Sticky Canary 对于建立对我们新的 GraphQL 服务的信心至关重要。
非幂等 API:这些测试与具有变异或非幂等特性的 API 兼容。
业务指标:Sticky Canary 验证了我们在迁移后的核心 Netflix 业务指标的改善。
系统性能:对延迟和资源使用情况的了解帮助我们理解迁移后扩展配置的变化。
注意事项
对客户造成负面影响:Sticky Canary 可能对真实用户产生影响。在将某些客户持续路由到新服务之前,我们需要对新服务有足够的信心。这在一定程度上通过实时影响检测得到缓解,该检测将自动取消实验。
短暂的:Sticky Canary 适用于短暂的实验。对于长期的测试,应使用全面的 AB 测试。
总结
技术不断变化,作为工程师,我们在职业生涯中的大部分时间都在进行迁移。问题不在于我们是否进行迁移,而在于我们是否能够安全、无停机时间地及时进行迁移。
在 Netflix,我们开发了一些工具,确保对每个特定的测试用例进行迁移的信心。我们介绍了 AB 测试、Replay 测试和 Sticky Canary 这三个用于 GraphQL 迁移的工具。
作者介绍:
Jennifer Shin、Tejas Shikhare、Will Emmanuel 均为 Netflix 高级软件工程师。
原文链接:
https://netflixtechblog.com/migrating-netflix-to-graphql-safely-8e1e4d4f1e72
相关阅读:
评论