写点什么

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:0011017

评论

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

低代码引擎半岁啦,来跟大家唠唠嗑...

阿里巴巴终端技术

前端 低代码

jquery 事件绑定及取消 bind live delegate on one区别 (超详细且通俗易懂)

Ankiee

jquery 11月月更

python常用内置函数用法精要(一)

乔乔

11月月更

Zebec开启多链布局,流支付生态持续扩张

西柚子

刘强东给京东高管降薪:2千多位总监兄弟工资打8折,并拿出100亿保障”兄弟“基础住房

小小怪下士

程序员 京东 刘强东

极客时间架构训练营模块七作业

李晨

架构

二面被RocketMQ虐后,狂刷这套实战到源码手册,再战阿里

钟奕礼

Java Java 面试 java程序员 java编程

集世界杯+GameFi元素的MetaElfLand,推出世界杯专场活动

西柚子

【收藏】设备的前期管理,你重视了吗?

PreMaint

设备管理

PCB做SET连片,转批量时发现利用率非常低,有遇到过吗?

华秋PCB

PCB PCB设计 拼板

10分钟让你了解应用宝APP上架流程

YonBuilder低代码开发平台

开发者

为什么要用 Tair 来服务低延时场景 - 从购物车升级说起

阿里技术

内存数据库 低延时

全面焕新|详解 Grafana v9.0.x 新增功能特性

阿里巴巴云原生

阿里云 云原生 Grafana 新功能

offset新探索:双管齐下,加速大数据量查询

IT科技苏辞

是时候考虑升级 JDK 17 了

世开 Coding

Java jdk JVM jdk17

7X24 高可用保障,火山引擎边缘函数为猿辅导在线教学业务保驾护航

火山引擎边缘云

Serverless 边缘计算 在线 教育 火山引擎

温州有等保测评机构吗?听说没有是吗?

行云管家

等保 等保测评

Java岗位必备技能SpringBoot的9道面试题集锦

钟奕礼

Java java程序员 java面试 java编程

分布式数据库Greenplum基本原理和使用

价投小邱

数据库 分布式数据库 greenplum

HummerRisk V0.5.2:升级对象存储、云检测、云审计和K8s资源态势等

HummerCloud

云原生 k8s #Kubernetes# 云原生安全

Serverless 的前世今生

Serverless Devs

华为云GaussDB打造金融行业坚实数据底座,共创数字金融新未来

清欢科技

NFT盲盒链游DAPP系统开发搭建技术

薇電13242772558

web3

VoneDAO助力元宇宙生态治理,加速组织数字化转型

旺链科技

区块链 产业区块链 DAO

从流程驱动到数据驱动 银行业数据平台架构的演进

酷克数据HashData

DHorse系列文章之镜像制作

tiandizhiguai

云原生 Serverless Kubernetes

双机热备与数据备份的关系说明一二

行云管家

数据备份 双机热备

使用 Bytebase 管理 Rainbond 上的应用数据库

北京好雨科技有限公司

集世界杯+GameFi元素的MetaElfLand,为何将在世界杯期间爆发?

鳄鱼视界

avm 开发 APP 怎么设置字体

YonBuilder低代码开发平台

kafka实战】分区重分配可能出现的问题和排查问题思路

石臻臻的杂货铺

kafka Kafka实战 11月月更

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