Duolingo是最受欢迎的语言学习平台,每天有3140万活跃用户数。向用户发送通知颇具挑战性,尤其是当目标用户数达到数百万时。顺便说一句,这里有一些通知的例子。
在下面描述的例子中,营销团队的需求是在特定时间(即在2024年的超级碗广告播放后几秒钟内)在5秒内发送超过600万条通知。2022年,Coinbase在超级碗期间推出了一项弹跳二维码活动,非常火爆,结果导致他们的网站崩溃。
Problems- 当前系统通常每秒处理大约10,000条通知,需要将通知发送速度提升到原来的80倍。
- 在Android应用中发现了一个问题。当它向Android应用发送通知时,会立即向后端发送一个请求。这有点像DDoS攻击。
- 系统应继续处理正常流量。
- 需求不断调整(能否在通知中添加一个图标?能否将其发送到更多城市?能否将推送本地化到不同的语言?能否使用供应商来完成这个工作?)
- 在Duolingo,一个操作原则是先测试。这意味着该解决方案应在此之前进行测试。
- 系统应能够按此速度扩展。涉及多种技术(如苹果和安卓API,AWS服务的扩展限制,某些服务的速率限制等)。
- 系统应尽可能在超级碗当天之前准备好。因为如果在活动前几天才扩展系统,那会花费很多成本。
解决方案
首先,需要明确变化的需求。也就是说,在最后几天做一些调整是可以的,但是有些调整是不允许的,比如“在基本确定了目标受众名单的前一天增加200万用户行不行?”答案是不行的,因为这么快的速度根本来不及做测试。而没有经过测试就不能发布。
速度问题是每秒处理800,000个请求。Duolingo在AWS上有许多服务。该项目相关的服务包括S3、DynamoDB和SQS。在市场活动开始前的几个月,团队将从DynamoDB(包含userId和deviceId)获取用户列表,然后将其存储在S3中。到了活动当天,工程师会扩展ASG(一组EC2实例)以及单独的EC2实例。工人将从S3中获取之前存储的数据,并将其存储在内存中。数据将按照用户ID映射到设备ID的方式存储。
之后,API服务器实际上会向FIFO,先进先出的SQS队列发送50多条消息。中间的中间处理者在接收这些消息后,他们会将大约10000条SQS消息发送到下一个队列。最后一级的最后,最后一级的通知工将通过调用批量处理APNS和FCM的API来发送通知,它们分别是苹果和谷歌的通知API。
但是SQS本身每秒的消息限制是120,000条消息。仅仅为了在5秒内发送数百万条通知,他们需要使用批量处理技术。他们将500名iOS用户放在一条消息中,而每条消息则包含250名Android用户,这样就满足了限制要求。
AWS能否按时提供所有必要的资源? 为了解决这个问题,他们联系了AWS的技术支持人员,这位人员帮助制定了《基础设施事件处理》文档,其中详细说明了步骤,比如何时扩容及如何扩容,还详细列出了具体步骤,例如缓存设置、缓存连接限制等,以及Dynamo的限制。此外,一个专用的ECS集群也解决了部分问题。
测试一下在最初的MVP阶段,测试使用了静默推送进行。这是一种发送一个空消息到客户端设备,看看会发生什么的方法。其中一个瓶颈是发现线程数量不足。由于他们使用的是Python应用程序,多线程程序存在一些已知的问题。将线程数量从10减到5,再减到1,这些调整帮助解决了这个问题。
当他们尝试扩展通知服务(专门为此项目设立)和后端时,又遇到了一个问题。该服务必须等待所有其他后端服务扩展完成,才能扩展,反之亦然,即它们必须互相等待。因此,他们之前提到的独立的ECS集群(之前提到的)就是为了这个原因。
在3个小时内检查了后端和通知服务的可用性也成功了。
在真实用户/设备上测试解决方案时,我们利用了一些现有的活动,例如万圣节相关的促销/通知使用了新的通知服务,该服务首次发送了100万条通知。一月份,他们用新年欢迎信息对400万用户进行了测试,效果也相当不错。
僵尸模式这个内部工具真的帮了大忙,特别是在测试过程中。僵尸模式本质上是指,当开启时,用户的设备会暂时停止向后端发送请求,直到尝试重新连接。这在后端无法处理流量激增并需要时间恢复时特别有用。这样使得使用真实用户进行测试变得更加方便。
竞选结果其实非常棒。99%的推送通知在5.7秒内发出,95%的推送通知在3.9秒内发出。
学到的教训- 对设计保持开放态度但测试要严格:他们承认设计远非最佳,但选择了一个允许迭代和测试的设计方案。他们认识到测试对于确保系统按预期运行至关重要。
- 重视系统的韧性与健壮性:系统必须设计成能够应对多个用户同时操作等挑战而不引发错误,例如发送出重复的消息。这突显了设计时预见并解决潜在问题的重要性。
- 为故障做计划并积极应对:他们接受了事情可能会出错这一事实,并采取了更积极主动的态度。他们制定了详细的指南手册,指导工程师在关键时刻采取何种行动,包括各种故障情景下的备用计划,例如完全的通知系统失效。这反映了他们面对问题时准备充分并积极解决问题的承诺。
看看源代码,了解更多关于挑战、解决方案和测试内容的信息。
👏点击订阅,获取更多精彩文章!🖥️
共同学习,写下你的评论
评论加载中...
作者其他优质文章