使用Uber Engineering的XP后台推送部署更可靠的应用程序

0
使用Uber Engineering的XP后台推送部署更可靠的应用程序

与服务器端编程不同的是,移动代码一旦发布就不能撤回,只有在用户选择应用程序升级时才能更新。对于优步工程来说,这是一个独特的挑战,涉及到增量发布新功能,修复bug,以及在我们的移动应用程序中大规模减少停机。

超级的实验平台(XP)负责确保新的移动功能尽可能无缝地为我们的用户推出。在正常的操作模式下,XP允许移动应用程序查询后端服务(治疗服务)来检索应该为特定用户打开的一组特征(标志)。然而,这就有问题了——而且漏洞百出!-当在XP负载返回到应用程序之前的代码中查询flags的状态时。

为了应对这些挑战,我们开发了XP后台推送,以安全有效地实时减少bug。与传统的基于拉的模型不同,我们的基于推的工具使我们能够主动强制用户的应用程序进入特定的配置,而不必等待应用程序调用后端服务并返回有效负载,使其更容易、更快速地修复uber规模的错误。

在本文中,我们将讨论这个强大的新工具如何使我们的工程师能够利用现有的Uber服务为用户部署更可靠的应用程序。

修复XP后台推送前的bug

如果没有XP后台推送,我们很难绝对确定在某个特性标志后面出现重大错误的情况下,我们可以将用户返回到工作状态。

以下面的理论场景为例:Uber在App v1中发布了一个新功能,我们后来发现,对于一些用户来说,这个功能会导致他们无法叫车。我们立即在应用程序v2中加入了这个错误的修复程序,但将v2上传到应用程序或谷歌Play商店需要时间。此外,即使新版本可供下载,用户也必须自愿升级补丁版本,只有自愿下载App v2的用户才会加入补丁。

理想情况下,我们可以通过我们的XP动态回滚v1中损坏的特性,让用户回到工作状态,直到他们升级到补丁的v2。在这个场景中,新功能隐藏在功能标志后面,这些标志的状态从我们的治疗服务(Treatment Service)查询,这是一个后端服务,决定向用户显示哪个“治疗”。治疗服务使我们能够控制推出服务器端和回滚错误功能,只需禁用一个标志。

这种服务器端控制功能非常强大,大多数时候都能正常工作。然而,仍然有一些边缘情况不能用传统的特性标记来处理,例如,当标记后面的代码出现在配置有效负载返回之前。这对Uber来说很重要,因为为了确保应用加载时间快速而无缝,标志是异步获取的。换句话说,我们倾向于只使用那些不会阻碍应用内UI使用的api。

考虑这样一个场景:当实验请求是非阻塞的时候:一个有bug的特性被一个标志所控制,并且在治疗服务负载返回之前在应用程序中检查这个标志。在“治疗服务”中,该标志为某些人群打开,但在第一次发射时,该标志将被禁用,因为有效载荷尚未到达。当有效载荷到达时,它被缓存以备后续发射。该标志背后的代码开始导致崩溃,因此该标志随后在治疗服务中被禁用。但是,该标志不能被禁用,因为它是在有效载荷到达之前检查的,并且崩溃发生在有效载荷(包含禁用标志所需的信息)被接收之前。

这种情况很不理想,可能会影响我们用户的优步体验。幸运的是,有了XP后台推送,这样的漏洞可以用你的手指来缓解——或者更确切地说,一个推送通知的传递。

使用推送通知修复bug

为了修复这些类型场景中的错误和解决崩溃,我们的XP后台推送使用无声推送通知来启用或禁用功能标志。如果存在需要修复的错误,我们会发送一个无声的推送通知,其中包含一个有效负载,指示应用程序打开或关闭某个功能,缓解应用程序的糟糕性能,直到该问题在未来版本中得到解决。

这在理论上听起来很简单,但实际上需要在服务之间进行深思熟虑的智能交互才能正确执行。向大量用户发送推送通知需要花费时间,并给我们的基础设施带来压力,因此在宕机的情况下向所有用户推送通知既不可行也不高效。

因此,第一个也是最棘手的问题是确定哪些用户受到bug的影响,因此需要向他们发送通知。由于Treatment Service负责评估标志状态并将其发送到移动客户端,因此它可以确定在特定用户的设备上启用了哪些标志,或者相反,在哪些用户设备上启用了特定标志。

XP后台推送工作流

图1:在我们的后台推送工作流中,推送是由开发人员通过web界面触发的。这将向GroupPusher发送一个有效负载和一个Cassandra键,GroupPusher从Cassandra中提取受影响的用户列表,并通过pushher将有效负载发送给所有用户。

我们利用Treatment Service通过将所有用户/设备对的评估结果记录到a来确定所有标志的状态这一事实卡夫卡的话题。这对象摄取主题Samza作业,数据被加载到卡珊德拉表用于数据库查找。Cassandra表存储了每个Uber账户中所有标志的最新治疗服务结果,其管道每秒处理超过1000个事件。

如下图2所示,一个推送过程是由工程师触发的,他们负责缓解应用程序中的问题:

图2:在回滚导致中断的标志时,Uber XP的用户可以选择通过无声的后台推送将新配置发送给受影响的用户。这意味着新配置将在用户打开应用程序时可用,而不是在应用程序请求负载时可用。

后台是我们的A/B测试平台,睡眠,构造需要根据新配置发送给用户的有效负载。这个有效负载被发送到一个名为GroupPusher的内部服务,以及一个标识需要回滚的标志的键。GroupPusher是一个服务,它接受一些在Cassandra中标识一组用户的键和一个有效负载,并继续将有效负载发送给所有标识的用户集。然后,GroupPusher根据这个键从Cassandra中提取受影响的用户列表。

GroupPusher接下来调用pushher,这是一个内部服务,以每秒约3,000次推送的速度将有效载荷发送给用户。pushher负责向用户发送推送通知,例如,让他们知道他们的司机正在接近他们的取车地点:“你的优步现在到了。”然后,pushher通过apn(适用于iOS)和GCM(适用于Android)将有效载荷发送到移动客户端。

此通知对用户是静默的,但在幕后,应用程序正在重新配置。当接收到有效负载时,标志配置将覆盖缓存中任何先前存在的标志状态,这将缓解错误,直到它可以使用更新的配置调用新的治疗服务有效负载。

对优步XP的长期推动

XP后台推送是作为减轻中断的工具开发的。每个Uber的应用程序都包含数百个,在某些情况下,数千个负责配置应用程序的标志。XP后台推送确保如果出现问题,我们的团队将能够解决它,只要它是由标志控制的。反过来,这种信心使我们能够为用户提供更加无缝的移动体验。

如果你愿意接受挑战,帮助我们发展Uber的XP,考虑申请我们团队的职位

图片标题:康纳·梅尔沃德(Conor Myhrvold)的《日落时穿过小路的长颈鹿剪影》,奥卡万戈三角洲,博茨瓦纳。

评论