写点什么

Agoda 的非常规客户端优先迁移:从 GraphQL 单体架构到微服务架构

作者:Eran Stiller

  • 2024-12-19
    北京
  • 本文字数:3184 字

    阅读完需:约 10 分钟

Agoda 的非常规客户端优先迁移:从 GraphQL 单体架构到微服务架构

Agoda 最近描述了它们从单体 GraphQL API 转向微服务架构的非常规方法。与侧重于优先拆解服务器端组件的传统方法不同,Agoda 采用了客户端优先的策略,使用一个内部智能编排器库来使其客户端应用程序准备好并行处理单体和微服务。


在服务器迁移之前,Agoda 优先考虑让客户端准备好处理单体和微服务,从而降低风险和所需的协调工作。Agoda 的助理开发经理 Numan Hanif 告诉 InfoQ:“这种方法最大限度地减少了中断,使我们的团队能够更好地控制整个堆栈,并使架构更好地与敏捷和现代开发原则保持一致。”


打破单体架构,拆分 GraphQL 单体架构 (来源)


内部智能编排器(Smart Orchestrator)是 Agoda 客户端优先迁移策略的关键组成部分,旨在在迁移期间将客户端应用程序与后端连接起来。它充当动态路由层,根据配置将请求定向到单体 GraphQL API 或新部署的 微服务。Agoda 的工程师更喜欢使用这种方法,而不是使用 Apollo Federation,后者与奈飞(Netflix)处理这种情况的方式相似。


发布与单体架构相同的接口允许客户端应用程序无需任何修改即可运行,从而减少了迁移过程中进行大量更改的需要。这种设置确保了客户端应用程序可以处理混合后端环境,为并行微服务开发奠定了基础。


智能编排器(Smart Orchestrator)根据配置路由客户端查询(来源)


除了路由之外,智能编排器(Smart Orchestrator)还自动管理模式更新和映射,支持迁移的增量特性。最初,所有模式都指向单体,但随着域的拆分,编排器更新了映射,将查询路由到正确的微服务上。


Agoda 以增量方式执行向微服务的迁移。每个新创建的微服务都经过了严格的单体测试,以验证数据的正确性,确保在转换客户端流量之前,两个系统的响应相匹配。此外,Agoda 还实施了一个准确性测试系统,在增量部署期间不断比较单体和微服务的输出,以进一步验证迁移。


Agoda 采用了一种自动化的数据驱动方法,在其 100 个应用程序 Git 存储库中分析和准备 GraphQL 查询,以确保在迁移过程中客户端准备就绪。使用生产数据,Agoda 根据域之间相互依赖的程度将查询分为简单、中等和复杂类型。


“拆解”跨域查询是 Agoda 迁移的关键一步。简单的查询不需要更改,而 Agoda 工程师将中等查询拆分为每个域单独的独立请求,并在客户端上合并结果。涉及紧密耦合嵌套域的复杂查询,当一个查询依赖于另一个查询的结果时,通常需要顺序执行,因此需要更广泛的重组。


“拆解”复杂查询(来源)


在拆分单体架构的同时,Agoda 专注于将现有代码原封不动地迁移到新的微服务中,从而导致了旧的技术问题转移到了新的微服务中。例如,Hanif 告诉 InfoQ,“Agoda 遇到了诸如缺少客户端速率限制等问题,这经常影响我们的运营。”他说,事后看来,“为了更好地实现这种平衡,我们应在迁移过程中实施重构实践,确保迁移后的架构更清洁、更高效。”


InfoQ 在采访 Hanif 的过程中,谈到了 Agoda 的微服务迁移、使用的方法以及吸取到的教训。

InfoQ:你能详细介绍一下你们决定从单体架构迁移到微服务架构的原因吗?哪些特定的增长指标或痛点是启动这一迁移的转折点?


Numan Hanif:供应商管理系统由一个由 7 人组成的专业工程团队管理,监督 70 多个通过 GraphQL、gRPC 和 REST 等多个接口交互的客户端服务。这个单体系统在处理重要流程方面至关重要,包括通过该单体系统进行预订确认。


在这个单体系统中,我们的平均变更交付周期(Agoda 使用的开发人员体验指标)环比增长了 12%,平均每月创建了 40 个合并请求(MR)。我们广泛的测试环境包括 9200 个单元和集成测试,这些测试大约需要一个小时才能运行完,并在计划运行中实现约 73% 的稳定性。


单体架构的设置还严重依赖于各种基础设施组件,并且难以管理不相关的域,从而导致了架构的复杂性。由于每季度积压 210 张操作票据和高昂的运维开销,以及知识孤岛和庞大的代码库,学习曲线很陡峭。


这些问题凸显了可扩展性解决方案的必要性,使得微服务成为增强该系统开发过程中的可管理性、可扩展性和敏捷性的理想选择。

InfoQ:你们是否遵循了任何特定的方法或框架来定义每个微服务的边界,比如领域驱动设计(DDD)或类似的实践?


Hanif:我们没有采用领域驱动设计(Domain-Driven Design,DDD)作为我们微服务边界的默认框架,而是根据我们的具体需求和 GraphQL API 的独特方面开发了一种定制方法。我们从自低而上的方法开始,分析数据库模式,并通过标记将表分类到特定的域中。这提供了一个与我们的数据管理模式相一致的基础结构,确保了识别服务边界的一致基础。


标记了表之后,我们将每个 GraphQL 端点与相应的表域对齐,以保持跨数据和服务边界的一致性。虽然 75% 的 GraphQL 端点域标记起来很简单,但剩下的 25% 却带来了挑战,因为它们涉及存储过程从多个域访问表的复杂模式。这种复杂性需要进一步的改进,以确保内聚的服务结构与我们的架构目标相一致。


我们的流程与 DDD 共享元素,例如将服务与业务功能对齐,但不同之处在于它是基于数据驱动、自底而上的方法。与自顶而下、领域专家主导的 DDD 方法不同,我们专注于现有的数据结构,并使用领域标记来解决 GraphQL 的独特挑战。这使我们能够创建连贯且功能一致的微服务,同时解决基础设施的操作复杂性。

InfoQ:是什么促使你们采用“客户端优先”的迁移方法?这一策略是否是基于以往的经验、理论优势或从以往项目中吸取的教训?Agoda 现有的架构或团队结构中是否存在任何特定的挑战,使这种方法特别适用?


Hanif:采用“客户端优先”的方法迁移到微服务的决定受到了理论和实践经验的影响。最初,我们考虑使用单体作为客户端通信的路由器,但这与我们实现真正的垂直(客户端数据库)所有权的目标相冲突。路由器最终将成为一个软单体,使长期架构变更变得复杂,并保持集中控制。这一见解强调了需要采取更分布式的策略。


过去采用服务器优先迁移方法的经验凸显了几个挑战,包括由于客户端迁移延迟而导致的迁移时间过长。这些瓶颈阻碍了我们完全停用单体架构的能力,并暂时推迟了微服务架构带来的好处。这些经验教训强调了首先让客户端做好准备的重要性,确保它们能够处理后端更改并促进无缝迁移的重要性。


客户端优先策略旨在通过允许后端开发与客户端准备活动同时进行来减少与外部团队的协调工作。这种方法最大限度地减少了中断,使我们的团队能够更好地控制整个堆栈,并使架构更好地与敏捷和现代开发原则保持一致。它还解决了诸如主动拼接查询、实现并行开发和减少依赖性之类的挑战,考虑到现有体系结构的复杂性,这一点尤其有益。

InfoQ:智能编排器(Smart Orchestrator)客户端库是内部构建的,还是你们根据需要调整了现有的工具?在创建和维护它的过程中,有哪些主要的挑战?对于处理 GraphQL 模式和路由的复杂性,你们是否发现了一些必要的特定特性?


Hanif:智能编排器(Smart Orchestrator)客户端库是内部开发的,用于解决现有解决方案无法满足的特定需求。这一决定允许使用定制工具,在不改变客户端接口的情况下,有效地管理跨微服务的模式更新和请求路由。自动模式映射更新等关键功能对于处理 GraphQL 的复杂性至关重要,可确保与现有客户端应用程序的无缝集成,同时可以避免嵌入式业务逻辑。


开发智能编排器(Smart Orchestrator)带来了挑战,每当迁移过程中出现问题时,都要用新的库版本更新多个存储库,这需要仔细的协调和测试。此外,在生产环境中启用 GraphQL 自检查询是至关重要的,但通常会由于安全和性能问题而受到限制。通过应对这些挑战,我们确保库始终是轻量级的,同时有效地支持跨域查询并适应我们的架构需求。

作者介绍


Eran Stiller 是澳大利亚墨尔本的首席软件架构师。作为一名经验丰富的软件架构师和首席技术官,Eran 设计、实施和审查了跨多个业务领域的各种软件解决方案。Eran 在软件开发领域拥有多年的经验,并有着丰富的公开演讲和社区贡献记录。


查看原文链接:

https://www.infoq.com/news/2024/11/agoda-graphql-microservices/

2024-12-19 08:0014477

评论

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

dubbo实战之二:与SpringBoot集成

爱好编程进阶

Java 程序员 后端开发

HotSpot JVM 内存管理

爱好编程进阶

Java 程序员 后端开发

Hexo 搭建:搭建与配置

爱好编程进阶

Java 程序员 后端开发

web前端培训React调度器原理分析

@零度

前端开发 React

20年最新金九银十面试必备,教你一份文档吊打面试官,拿到offer

爱好编程进阶

Java 程序员 后端开发

BS-XX-007基于JSP实现户籍管理系统

爱好编程进阶

Java 程序员 后端开发

20 数据存储服务器集群的伸缩性设计

爱好编程进阶

Java 程序员 后端开发

字节跳动构建Data Catalog数据目录系统的实践

字节跳动数据平台

数据库 字节跳动 数据治理 数据目录

Java8-Stream:2万字20个实例,玩转集合的筛选

爱好编程进阶

Java 程序员 后端开发

2021最新一次Java面试,快手三面一轮游,如今已拿意向书

爱好编程进阶

Java 程序员 后端开发

2021最新分享Java面试题库万字精华 github上标星80

爱好编程进阶

Java 程序员 后端开发

大规模并行分布式深度学习

阿里云大数据AI技术

人工智能 深度学习 并行分布式训练

CXF webservice之手动启动服务方法(restful )

爱好编程进阶

Java 程序员 后端开发

卫剑钒:《大教堂与集市》被过誉了吗?

腾源会

开源 腾源会

DockerFile的编写构建镜像步骤,常用命令和案例

爱好编程进阶

Java 程序员 后端开发

Docker下Prometheus和Grafana三部曲之三:自定义监控项开发和配置

爱好编程进阶

Java 程序员 后端开发

Java agent还不了解的程序员该反省一下了

爱好编程进阶

Java 程序员 后端开发

想从单体架构演进到分布式架构,SBA 会是一个不错的选择

华为云开发者联盟

架构 微服务架构 分布式架构 单体架构 SBA

中国全球GPU市场竞争格局分析

Finovy Cloud

人工智能 gpu 云服务器

Java Script

爱好编程进阶

Java 程序员 后端开发

企业文档协作如何进行?

小炮

文档协同

FusionStorage原理及组件

爱好编程进阶

Java 程序员 后端开发

18 张图,一文了解 8 种常见的数据结构

爱好编程进阶

Java 程序员 后端开发

2021最新Java学习路线,自学者的福利

爱好编程进阶

Java 程序员 后端开发

28岁程序身价过亿,从字节提前“退休

爱好编程进阶

Java 程序员 后端开发

Dubbo如何处理业务异常,这个一定要知道哦!

爱好编程进阶

Java 程序员 后端开发

小平邦彦:树懒style的世界一流数学家

图灵教育

数学 数学史 数学家

基于语义感知SBST的API场景测试智能生成

华为云开发者联盟

测试 语义感知 SBST 动态修正 ODG图

hadoop

爱好编程进阶

Java 程序员 后端开发

@RequestParam、@ModelAttribute、

爱好编程进阶

Java 程序员 后端开发

Docker Swarm从部署到基本操作

爱好编程进阶

Java 程序员 后端开发

Agoda 的非常规客户端优先迁移:从 GraphQL 单体架构到微服务架构_微服务_InfoQ精选文章