网飞Netflix如何将安卓的API单体后端迁移到微服务架构?


作为 Android 开发人员,我们通常可以奢侈地将后端视为在云中运行的魔术盒,忠实地返回给我们 JSON。在 Netflix,我们采用了前端后端 (BFF) 模式:我们没有一个通用的“后端 API”,而是每种客户端(Android/iOS/TV/Web)一个后端。在 Android 团队中,虽然我们大部分时间都花在开发应用程序上,但我们还负责维护与应用程序通信的后端及其编排代码。
最近,我们完成了一个为期一年的项目,将我们的后端与之前使用的集中式模型重新构建和解耦。我们在没有减慢发布的通常节奏的情况下进行了此迁移,并且特别注意避免对用户体验产生任何负面影响。我们从单体服务中的基本无服务器模型转变为部署和维护托管我们的应用程序后端端点的新微服务。这让 Android 工程师对我们如何获取数据有更多的控制和可观察性。在这篇博文中,我们将讨论我们的迁移方法、我们采用的策略以及我们为支持迁移而构建的工具。
...点击标题
 
缺点
在打破单体的艰巨过程中,您可能会收到一两个锋利的碎片。下面的很多内容都不是针对 Android 的,但我们想简要提及这些问题,因为它们最终确实影响了我们的应用程序。

  • 延迟

旧api服务在同一台“机器”上运行,该机器还缓存了大量视频元数据(按设计)。这意味着静态数据(例如视频标题、描述)可以被主动缓存并跨多个请求重复使用。但是,使用新的微服务,即使获取缓存数据也需要引起网络往返,这增加了一些延迟。
这听起来像是“单体 vs 微服务”的经典例子,但实际情况要复杂一些。单体应用基本上还在与许多下游微服务对话:它恰好有一个定制设计的缓存,帮助很大。更好的可观察性和更高效的请求批处理减轻了这种增加的延迟。但是,对于一小部分请求,经过多次优化尝试后,我们只需要承受高延迟:有时,没有灵丹妙药。
  • 增加部分查询错误

由于对端点的每次调用都可能需要向 api 服务发出多个请求,因此其中一些调用可能会失败,从而使我们得到部分数据。处理此类部分查询错误并不是一个新问题:它融入了 Falcor 或 GraphQL 等复合协议的本质。但是,随着我们将路由处理程序移动到新的微服务中,我们现在引入了用于获取任何数据的网络边界。
这意味着我们现在遇到了由于自定义缓存而无法实现的部分状态。我们在迁移开始时并没有完全意识到这个问题:我们只有在我们的一些反序列化数据对象有null字段时才看到它。由于我们的很多代码都使用 Kotlin,这些部分数据对象会导致立即崩溃,这有助于我们及早发现问题:在它投入生产之前。
由于部分错误增加,我们不得不改进整体错误处理方法并探索将网络错误影响降至最低的方法。在某些情况下,我们还在端点或客户端代码上添加了自定义重试逻辑。