
Grab基于Temporal构建了新的GrabUnlimited架构。该公司增强了用户体验,并将其服务于数百万用户的订阅平台的生产事件减少了 80%。新架构显著提高了系统的鲁棒性和可扩展性,解决了之前解决方案中的一系列问题。
GrabUnlimited 是 Grab 的订阅计划,为按月付费的会员提供福利。支持 GrabUnlimited 的平台实现了两个主要流程:一个是注册会员,另一个是更新会员。随着订阅者基数的增长,该公司开始遇到问题和系统中断。根据运维指标,Grab 观察到用户因数据库中会员状态损坏而被阻止、会员资格未能自动续订,或用户在续订后未收到福利等问题。
Grab 的工程经理Michel Parreno和首席工程师Theodore Felix Leo描述了在初始架构中遇到的问题:
随着最初的成功,从 2022 年 1 月到 2023 年 6 月,订阅者数量大幅增加超过 1000%,支持 GrabUnlimited 的架构开始出现压力迹象。常见的订阅者问题,如未收到会员福利,以及开发者问题,表现为服务中断次数增加,突显了系统的低弹性。罪魁祸首是什么?一个后端服务,虽然功能强大,但并未被没有被构建来有效地管理快速扩展的成员模型的复杂性。
GrabUnlimited 的原始架构依赖于Amazon RDS进行数据存储,SQS进行消息传递,Redis进行缓存和分布式加锁。采用状态机模式来跟踪成员状态。随着时间的推移,由于订阅者数量不断增加,用于检索到期续订会员的每日 cron 作业变得越来越慢。开发团队不得不将任务分成多个批次,并最终垂直扩展数据库。此外,由于 5 分钟 Redis 锁的限制,续订过程可能导致会员状态损坏。

GrabUnlimited 的原始架构(来源:Grab的工程博客)
该解决方案还存在弹性问题,即上游服务的中断,加上 SQS 重试没有指数回退,可能会导致服务在恢复上线时超载。最后,随着状态转换数量的增加,原始架构中的订阅服务变得过于复杂。它还缺乏幂等性保证,导致在重试过程中福利被重复授予。
在考虑了原有架构的问题及其对用户体验和运维开销的影响之后,团队开始寻找解决方案。工程师们没有选择重构现有的系统,而是选择基于Temporal,(Grab 的另一个团队之前采用的开源工作流编排引擎),用一个新的架构取代现有的架构。
团队仔细评估了 Temporal 的多个方面,包括可扩展性、可靠性、性能、安全性,以及开发工作量、成本和可测试性。新架构得益于 Temporal 的许多内置特性,如无限重试、指数回退、速率限制和可观测性。

使用 Temporal 构建 GrabUnlimited 的新架构(来源:Grab的工程博客)
在新架构中,每天的 cron 作业被Timer替换,它允许根据用户的订阅时间将续订过程在一天中分散进行,从而大大提高了可扩展性。通过利用 Temporal 的内置工作流执行能力,解决了之前的并发挑战,相同的工作流ID被分配给运行互斥操作的多个工作流实例。
团队还利用了 Temporal 的弹性机制(如无限重试和指数回退)来配置适当的重试策略,以防止外部服务在短暂的可用性问题出现时被压垮。通过设计工作流步骤来处理不同的责任,并利用 Temporal 进行错误处理和工作流执行的排序,解决了之前架构中的幂等性问题。
在采用 Temporal 的过程中,GrabUnlimited 团队学到了很多,并不得不调整他们对系统设计的方法,以充分利用 Temporal 的功能。工程师们强调,这种转变使他们能够专注于产品平台的重要方面,而不是花费时间实现基本构建块。尽管采用新技术存在挑战,但团队相信“学习曲线是有回报的”。
原文链接:
评论