1808亿次,16倍的超越!谈支付宝红包的高并发挑战
发布时间:2016-08-10 15:44
近年来,随着技术的发展,通过网络或者社交媒体“抢红包”逐渐成为节日里面新的特色,尤其是在除夕夜,大家边看春晚直播边手中不停地咻咻咻抢红包更是十分有趣。然而这后面的抢红包带来的高并发的挑战又是如何应对的呢?本文就为你揭晓答案。
与传统意义上的红包相比,近两年火起来的“红包”,似乎才是如今春节的一大重头戏。历经上千年时代传承与变迁,春节发红包早已成为历史沉淀的文化习俗,融入了民族的血脉。按照各家公布的数据,除夕全天微信用户红包总发送量达到80.8亿个,红包峰值收发量为40.9万个/秒。春晚直播期间讨论春晚的微博达到5191万条,网友互动量达到1.15亿,网友抢微博红包的总次数超过8亿次。
为此,InfoQ策划了“春节红包”系列文章,以期为读者剖析各大平台的红包活动背后的技术细节。本文为支付宝篇。
蚂蚁金服旗下的支付宝经过十几年的发展,从简单的支付工具逐步发展成互联网金融平台。2013年余额宝的崛起就是互联网金融平台升级的标志型事件,这一年支付宝顺利进行了PC向无线的布局,可以说架构成功升级到移动互联网金融平台。经过两年的发展,2015年口碑和社交业务的崛起让支付宝架构进一步在原有架构基础上拓展出支持线下市场和社交的生活互动型架构。2015年钱包9.0的发布,这个里程碑式的项目初步奠定了支付+移动互联网金融+生活互动型混合架构。演进示意图如图1所示。
图1 架构演进示意图
项目保障体系
2015年12月份,我们在第一时间得知支付宝中标央视消息后,既兴奋又担心!兴奋的是,这是一次千载难逢的机会,我们终于可以一展身手。担心的是,支付宝和央视联合搞活动,是我们有史以来最大规模的活动,到底规模多大,我们没有任何概念。唯一能得到的信息是,历年观看春晚的人数大约在7亿多,支付宝的年度活跃用户4亿多,至于用户的行为习惯,没有任何参考模型。
虽然心里不是很有谱,但也没那么担心,信心来自于两方面。
1)经历过这么多年的双11和去年的除夕,多年经验的沉淀,我们对超大规模的活动沉淀总结出一整套预测模型,而且这个预测模型经过了多次实战检验,相对比较准确。
2)从钱包9.0开始,我们已经开始布局生活服务平台,这个版本搭建起社交和口碑两个平台的雏形,架构上从移动互联网金融架构扩展出能支撑生活互动型的架构,形成了支付+互联网金融+生活互动的混合架构,这种架构体系既能支持移动互联网金融的高可用、资金安全、高弹性伸缩,又能支持生活互动型架构的轻巧、灵便、弹性十足的特点。架构示意图如图2所示。
图2 总体架构示意图
团队在拿到中标信息后,我们迅速决策,达成了以下指导原则:优先确保核心链路,保证核心链路上用户体验顺畅。万一出现系统容量不足,系统必须能扛住洪峰,不被压垮,即使这种情况下也要给用户尽量友好的提示文案。在确保主链路基础上,还需要照顾到支付宝App内几百个非关键链路,对于非关键链路按照业务重要程度分为4个等级,根据等级分配不同的资源配置。
经过2个月的精心准备,在激动人心的4小时结束后,整个春晚支付宝系统稳稳地扛住了4波洪峰,表现平稳,无论是核心链路还是非核心链路,没有出现任何问题。4个小时内几乎没有用户因为系统、功能上的问题而产生投诉,客服同学没有任何咨询压力。
用户“咻一咻”在第二场活动达到高潮,累计互动次数达到1808亿次,是去年的16倍。20点38分,“咻一咻”峰值达到177亿次/分钟。可以想象一下,几亿用户同时拿着手机,以想戳透手机屏幕的速度点击咻咻按钮,几亿的请求瞬间从客户端洪水般涌入服务端,对后台将是多大的压力!这么高并发情况下,如果系统设计不合理或者预测模型不准确,将立即被冲垮,应用系统一旦被冲垮,高压下根本没有恢复的机会。
五项准备
为了保证整个春晚顺利进行,我们在以下5个方面做足了功课。
1)相对合理的超大规模压力预测模型。前提约束条件要说明下,服务器资源是有限的。总共这么多服务器,要充分利用起来需要两个条件。
-
应用架构必须可以大规模扩容。如果架构不合理,即使有服务器也没法扩容,刚好在架构演进的过程中,支付宝App服务端进行了LDC单元化改造,扩容对我们来说so easy。
-
模型要尽量准确。模型不准确的后果是用户的行为习惯和预期不同,导致部分业务压力特别大,无法正常提供服务,而另外部分服务器十分空闲,占着机器资源不干活。
2)核心链路和非核心链路彻底梳理。核心链路梳理和非核心链路梳理相对比较容易,注意以下5点。
-
接入层必须具备足够富裕的容量支撑,即使因为评估不准浪费部分机器也是可以容忍的。接入层一旦出问题,所有业务将全军覆没。如果接入层足够健壮,当某个业务抗不住时,完全可以通过限流来隔离这个业务,而其他业务不受任何影响。
-
用户必须能进得来。也就是要保证用户能顺利登陆进来,如果用户连登陆都受限制,体验肯定好不到哪儿去。
-
用户要能玩起来。这是核心业务逻辑,如果咻都没法咻,或者咻了半天红包或者福卡发不出去,那也是致命的。
-
要能保证用户能传播和互动起来,包括分享、加好友、聊天。
-
非核心业务需要进行合理分级。我们大致分了4档。第一档4个tab,非核心链路中的最高优先级,必须力保。第二档1级入口,容量必须是平时的几十倍。第三档2级入口,容量是平时的十几倍。第四档,一、二、三档外的其他业务,要保证系统具备自我保护能力,底线是不能被压跨。
3)大规模生产系统全链路压测。核心链路和非核心链路梳理清楚了,进行了性能优化和系统扩容后,能否达到我们预测的目标值,要靠线上全链路压测来验证。全链路压测相应的原则:核心链路必须全部覆盖,包括单独压测和混合压测,非核心链路要尽最大可能覆盖。经过项目组的努力,全链路压测基本覆盖了所有的核心链路和非核心链路,覆盖率接近100%。单系统或接口压测问题不大,但混合压测就比较头痛,主要还是用户行为预测的问题,为了确保万无一失,在混合压测时组合出多个模型进行压测,尽最大可能暴露出系统的性能和容量问题。
4) 高频次灰度内测和线上小规模活动预热(2月1日和2月4日两次小规模活动)。高频次的内部灰度测试更主要是能暴露出一些比较隐蔽的功能问题,能进行充分的业务配置演练。而两次小规模预热则起到了更大的作用,虽然规模没有春晚大,但用户行为习惯具备一定的参考性,并能相对真实地模拟春晚活动。我们在这两次预热活动中确实也发现了一些问题,并且根据相对真实的用户行为习惯对系统容量进行了调整和优化,有效地防止了春晚出现资源分配不均的问题。
5) 上千个业务、技术预案和完备的应急响应体系支持。业务上主要参数化、配置化,通过服务端来控制客户端的行为,以满足业务多样性需求,降低客户端版本升级困难带来的冲击。技术上预案分为提前预案和应急预案。提前预案主要作用是让服务器轻装上阵,将计算能力节省下来供核心功能使用,比如降级日志、关掉定时任务等。而应急预案更主要是用来保命的,万一系统在某些点出现了意外状况,会通过所谓的大招以牺牲部分非核心业务来保核心业务,也就是丢卒保车。当然春晚因为前期工作做得比较到位,这些大招都深藏闺阁,没机会施展。
八大技术难点
这么超大规模的活动,肯定存在很多技术难点,平时看不起眼的一个问题,在超大规模情况下,就可能被放大。接下来简短总结这些技术难点。
1) 登陆:去年除夕,我们登陆上容量做的不足,导致用户在登陆时就被挡在门外。本次春晚,我们做了硬性规定,必须能顺利登陆进来,坚决不允许出现因为登陆系统处理能力不足而导致出现限流这种很不好的体验。去年的登陆峰值大约在十几万每秒,今年我们提出实现百万登陆能力,这个量是平时量的200倍左右,也是去年除夕峰值的6、7倍,而我们用户数量也仅仅增长了2,3倍,百万级别应该没有问题,而实际上登陆量确实也在这个数量级。
目标确定好了,接下来比较难的就是如何做到这个系统容量目标。性能优化和扩容两手抓,而且更多的是要靠性能优化,作为有追求的工程师扩容不应该是首选。经过1个月左右极致的性能优化,最终机器仅仅扩容到原来的4倍,大约在几千台,其他的提升全部通过性能优化实现。
2) 如何应对洪峰(图3是简单的架构示意图):可以想象,几亿用户同时在线,在几乎同一时刻进行咻咻操作,瞬间洪水般流量直接冲进来,当时秒级峰值达到了2.95亿次。对于这么大的流量,我们使用了漏斗形的分流、导流方案。客户端请求到我们的网络设备后,从应用视角我们大体分为三层LVS、spanner、gateway。这儿你可以看作一个漏斗,越往里层,可以处理的请求越小。之所以这么设计,还是基于业务和用户体验,对于咻一咻,虽然有2.95亿次请求,但我们的奖品个数是有限的,每场只有6000万个现金红包和上亿张福卡。如果发奖能力达到了6000万每秒,那6000万个现金红包瞬间被秒光,这也不是业务和用户想看到的。我们平衡下来,将奖品(现金红包+福卡)发放能力设定在100万每秒,大约可以在几分钟内顺利发完这6000万个现金红包。
这里有几个关键点,gateway的处理能力是千万级别,集中咻咻大约用掉了100万,剩下900万是给其他业务的。当大量咻咻请求没到gateway时,lvs和spanner要能正确处理,给用户比较好的体验,不能出现任何限流问题,这也符合用户没有中奖预期。我们的处理方案是,如果咻咻请求没到后端,给用户随机显示彩蛋(包括文案、图片、视频等)。对于spanner虽然处在网络更外层,但也需要理解部分业务逻辑。比如要能识别出不同的rpc请求,尤其是要能区分出咻咻接口。如果spanner不做任何识别,只管向网关转发1000万请求,那肯定将导致转发的咻咻请求超过100万,而挤占了其他业务的配额,导致其他业务被spanner限流无法正常处理。
图3 网络漏斗模型示意图
3)活动奖品控制系统:春晚一共搞了4场活动,大约发了2.3亿个现金红包和十几亿张福卡。在这么大规模的活动下,我们做到了0差错0资损,没有多发或者少发一个红包,严格控制了福卡的发放比例,也合理控制了发奖速度。4场活动基本控制在3-5分钟内完成,严格按照我们设定的预期模型执行。所有这些都得益于我们的奖品控制系统,对于这个系统设计上有3个基本原则。
-
资金0资损。
-
百万级的奖品处理能力。
-
灵活的奖品发放控制。
4)动态技术:客户端的一个最大的问题就是版本发布,有个成语叫做“覆水难收”,刚好比较形象地说明了这个问题。版本一旦发布,如果有问题需要让用户再次升级,时间已经来不急了。
为了更好地控制客户端的行为,参数化、配置化就成了必不可少的利器。但参数化、配置化带来了两个问题:
-
客户端预埋了很多逻辑,极大的增加了代码复杂度,客户端的代码测试难度加大,质量很难保证。
-
因为参数化、配置化,需要有机制能够保证配置数据能尽可能实时下发给几亿客户端,并且在最短的时间内生效。
对于客户端复杂度增大的问题,主要通过多套机制保障。
-
传统的质量保障,加强测试力度。
-
进行不同范围内的人群进行灰度。
-
安排多轮演练,模拟各种配置场景。
-
为了保证春晚的万无一失,年前增加了几场小规模预热,通过预热发现尽可能多的问题,并进行规避。
-
客户端版本发布后,产生的部分bug,必须修复,通过热补丁的方式,在不发布版本的情况下修复这些bug。
对于配置的实时下发,我们单独做了一套机制,使用推拉结合的方式,在最短的时间内下发配置信息。以服务端推送为主,通过sync机制,只要用户在线,尽最大可能将配置数据推送到客户端,万一有极少量配置推送失败,还可以通过拉的方式进行补偿,这样确保了配置数据一定能下发到客户端。
5) 资源管理:在这次春晚活动中,涉及到大量的资源,包括图片、拜年视频等。图片和视频都比较大,十几b到几百kb不等。当在高峰期时,如果瞬间有海量的请求到CDN上,这么大的请求带宽根本扛不住。我们当时预估了大约有几T的带宽需求。
为了能有效地扛住瞬间峰值对CDN的压力,我们对资源进行了有效的管理和控制。首先在客户端预埋了几个缺省资源,万一真不行了,这几个资源可以用。其次尽量提前打开入口,当用户浏览过后,就将资源下载到本地。再次浏览时不再需要远程访问CDN。最后,做了应急预案,高峰期一旦发现流量告警,紧急从视频切换到图片,降低带宽压力,确保不出现带宽不够而发生限流导致的黑屏等体验不好的问题。
最后的结果可以用完美来形容,由于预热充分,带宽虽然很高,但没达到我们的告警值,应急预案也没有使用。
6) 实时数据计算能力:红包剩余个数尽可能实时准确显示。这里有一个细节,当咻咻的时候,红包剩余个数随着你咻咻在不停的递减,而且递减的个数比较平滑,不像某些App,出现长时间不动,动一次就是断崖式变化。虽然这是一个不起眼的细节,但我们为了给用户更好的体验,让没抢到红包的用户能在最短的时间内知道尽量准确的红包剩余个数,我们解决了这个技术难题。
我们充分利用了两个方面的能力。一是实时的流式计算处理能力,可以在秒级收集各个服务器处理的红包个数,并且进行汇总计算,并把这个计算结果写在缓存中。另一方面我们充分利用每个请求头的控制信息,在用户每次请求的同时带回剩余个数。客户端收到应答后,如果发现本次请求没有中奖,从头部控制信息中解析出红包剩余个数并正确显示。
7) 全链路压测:支付宝有一套非常强大的线上环境压测的利器,能够模拟出你所想要的任何请求场景。对于参与用户量非常大的活动,前期再完备的准备,也不能确保一定不出问题,需要对线上环境进行性能压测。在全链路压测机制下你不仅仅可以知道各个应用系统的容量水位和目标之间的差距,还能够知道整个基础设施层,比如数据库、网络、存储等的瓶颈,让你能够根据压测数据进行快速决策。
8) 超大规模活动弹性计算能力:这么大规模的活动,初步计算下来,大约需要几万台机器,包括应用服务器、存储、网络设备等。对于这么大量的资源调配,如果没有金融云高弹性能力,短时间内部署完成,这是不可想象的。得益于金融云的高弹性能力,我们基本做到在1周内完成了相关资源的调配部署。
小结
2016年春晚在轰轰烈烈中过去了,我们收获了很多,其中最重要的一点是我们对春晚的用户行为有个初步的了解,如果再搞这种超大规模的活动,预测模型将更加精确。如果2017年央视春晚我们继续中标,我们将做得更加从容,更加顺滑,真正做到喝着咖啡过春晚!