写点什么

安全地将 Netflix 迁移到 GraphQL

  • 2023-07-04
    北京
  • 本文字数:4021 字

    阅读完需:约 13 分钟

安全地将 Netflix 迁移到 GraphQL

导读:本文介绍了 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 节点形式显示的差异。你可以在逗号左侧的括号中看到对照值,而在右侧则是实验值。

 

/data/videos/0/tags/3/id: (81496962, null)/data/videos/0/tags/5/displayName: (Série, value: “S\303\251rie”)
复制代码

 

我们在上述情况中捕获了两个差异,第一个差异是实验中缺少了一个 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


相关阅读:

GraphQL vs REST API 架构,谁更胜一筹?

GraphQL:API 的未来

为什么你的下一个 API 应该是 GraphQL 而不是 REST

2023-07-04 16:233838

评论

发布
暂无评论
发现更多内容

Flink X Hologres 构建企业级 Streaming Warehouse

Apache Flink

大数据 flink 实时计算

无需依赖Docker环境制作镜像

tiandizhiguai

Docker k8s

「 数据结构与算法 」如何系统性的学习数据结构与算法

小刘学编程

Java 学习路线 数据结构与算法

【Java基础】常用序列化技术与方式

No8g攻城狮

通信协议 网络通信协议

Python 内置界面开发框架 Tkinter入门篇 丁

eng八戒

Python GUI tkinter

ChatGPT入门案例|商务智能对话客服(二)| 社区征文

TiAmo

openai ChatGPT

软件测试 | App结构概述

测吧(北京)科技有限公司

测试

运维训练营第14周作业

好吃不贵

「 技术文章翻译 」jasypt-spring-boot敏感信息加密解密利器使用指南

小刘学编程

加密解密 springboot jasypt

「 Java开发规范 」10人小团队Java开发规范参考这篇就够了

小刘学编程

Java 数据库规范 代码规范 项目规范

GuitarPro2024免费版吉他打谱工具

茶色酒

GuitarPro

我不想再传递 nameof 了

newbe36524

C# Docker Kubernetes

「 代码性能优化 」java高级程序员必知必会的55个代码性能优化技巧

小刘学编程

Java 性能优化 高级程序员 代码技巧

「 代码性能优化 」作为一名Java程序员,你真的了解 synchronized 吗?(三)

小刘学编程

Java 性能优化 synchronized java锁

2023-02-15:商场中有一展柜A,其大小固定,现已被不同的商品摆满, 商家提供了一些新商品B,需要对A中的部分商品进行更新替换, B中的商品可以自由使用,也就是可以用B中的任何商品替换A中的任何

福大大架构师每日一题

算法 rust 福大大

Python 内置界面开发框架 Tkinter入门篇 丙

eng八戒

Python GUI tkinter

极客时间运维进阶训练营第十四周作业

9527

MASA Stack 1.0 发布会 —— 社区问题解答

MASA技术团队

.net stack 应用现代化 MASA

EasyRecovery2023新版本有哪些新功能?

茶色酒

EasyRecovery EasyRecovery15 easyrecovery2023

「 代码性能优化 」作为一名Java程序员,你真的了解 synchronized 吗?(一)

小刘学编程

Java 性能优化 synchronized java锁

模块六作业

张贺

ChatGPT这波热潮会不会让我失业?

eng八戒

人工智能 AI 聊天机器人 openai ChatGPT

CleanMyMacX4.12.5中文版苹果电脑管家

茶色酒

CleanMyMacX4.12.5

【2023年最新】轻松搞定MySQL数据库迁移

NineData

MySQL 数据库迁移 数据复制 数据迁移 SqlServer

研发提效:服务端技术方案模板参考

邴越

技术方案 模版

「 代码性能优化 」作为一名Java程序员,你真的会写for循环吗?

小刘学编程

Java 性能优化 for循环 技巧总结

「 前端开发规范 」10人小团队前端开发规范参考这篇就够了

小刘学编程

前端 统一代码规范 高效协同

嵌入式ARM设计编程(二) 字符串拷贝

timerring

arm

「 代码性能优化 」作为一名Java程序员,你真的了解 synchronized 吗?(二)

小刘学编程

Java 性能优化 synchronized java锁

自媒体营销或已死,内容营销为何越来越难做?

石头IT视角

面试必问:JVM 如何确定死亡对象?

王磊

java面试

安全地将 Netflix 迁移到 GraphQL_框架_Netflix工程博客_InfoQ精选文章