2W台服务器、每秒数亿请求,微信如何不“失控”?
微信作为当之无愧的国民级应用,系统复杂程度超乎想象:其后台由三千多个移动服务构成,每天需处理大约十的10~11次方个外部请求,整体需要每秒处理大约几亿个请求!那么微信究竟是如何保证系统稳定性并有序处理各类请求的?本文的作者从技术上深入解读了《用于扩展微信微服务的过载控制》一文,介绍了已在微信上运行了五年之久的过载控制系统DAGOR。
以下为译文:
最近我读了一篇论文《Overload control for scaling WeChat microservices(用于扩展微信微服务的过载控制)》,十分喜欢。
这篇论文主要分两部分:首先,我们能了解一些微信后台的内部消息;其次,作者分享了一种经过实践检验的过载控制系统DAGOR,该系统已经在微信上运行了五年。友情提示,这个系统在设计时就考虑了微服务架构的特殊情况,所以如果你想在自己的微服务上采用某种策略,那最好还是以这个系统为起点参考。
1.每秒需要处理几亿请求的微信后台
现在的微信后台由3000多个移动服务构成,包括实时消息、社交网络、移动支付和第三方认证等,平台每天能处理大约1010~1011外部请求。每个请求可能触发更多的内部请求,所以微信的后台作为一个整体,需要每秒处理大约几亿个请求。
“微信的微服务包含3000多个服务,运行在微信业务系统中的20000多台机器上,随着微信越来越流行,这个数字还在不断增加……由于微信一直在不断发展,它的微服务系统也在迅速更新。例如,从2018年3月到5月间,微信的微服务平均每天大约有1000个修改。”
微信将微服务分类为“入口层”服务(接收外部请求的前端服务)、“共享层”服务(中间层协调服务)和“基本服务”(不调用其他服务的服务,请求在这里终结)。
图1 微信的微服务架构
每天,峰值请求大约是日平均请求的三倍。在每一年的固定时期(例如在中国的新年前后),峰值负载可能达到日平均负载的10倍。
2.基于微服务的大型平台过载控制的难点
“过载控制……对于在任何不可预测的负载高峰下都要保证24x7服务大型在线应用来说极其重要。”
传统的过载控制机制主要用于只有少量服务组件的情况,通常包括一个较窄的“前门”,加上一些不重要的依赖。
“……现代的在线服务的架构和依赖变得越来越复杂,远远超过了传统过载控制的设计考虑。”
发送到微信后台的请求没有单一的入口点,而传统方式是在全局入口点(网关)上以中心化的负载监视为主,因此无法使用。
特定请求的服务调用图可能依赖于请求自身的数据和服务参数,甚至同一种请求的调用图都可能不同。所以,当特定服务出现过载时,很难确定应该拒绝哪一种请求来缓解压力。
过度的请求拒绝(特别是在调用图深处或者请求处理后期拒绝)会浪费大量计算资源,而且会由于高延迟而影响用户体验。
由于服务的调用图非常复杂,而且在不断变化,有效的跨服务协调的维护成本和系统额外开销非常高。
由于一个服务可能向它依赖的服务发出多个请求,还可能给多个后台服务发出请求,所以在处理过载控制时必须谨慎。作者采用了“序列过载”来描述多于一个过载服务被调用的情况,或一个过载服务被调用多次的情况。
“序列过载给有效的过载控制带来了挑战。直觉上,当服务过载时随机进行load shedding能将系统的吞吐量维持在饱和状态。但是,序列过载可能会导致吞吐量出现预期之外的下降……”
考虑一个简单的情况,服务A调用服务B两次。如果B拒绝掉一半的请求,那么A的成功率就会下降到0.25。
3.微信的过载控制系统DAGOR
微信的过载控制系统叫做DAGOR,它的目标是给所有服务提供过载控制,因此被设计成与服务无关。过载控制运行在单个服务器的粒度上,因为中心化的全局协调太昂贵了。但是,它能够与轻量级的服务器间合作协议配合使用,后者在处理序列过载的情况时是必须的。最后,DAGOR应当在load shedding不可避免时尽可能维持服务的成功率。消耗在失败的任务上的计算资源(如CPU、I/O等)应当保持最小。
我们要解决两个最基本的任务:检测过载状况,决定检测到过载后的对策。
过载检测
对于过载检测,DAGOR采用了等待队列请求平均等待时间(即排队时间)。排队时间可以有效地避免调用图中的延迟造成的影响(可以与其他指标比较一下,比如请求处理时间等)。即使过载没有发生,本地服务器上的服务处理时间也可能增加。DAGOR基于窗口进行监视,窗口大小为1秒或2000个请求,先到者为准。显然,微信做得不错:
“对于过载检测,考虑到微信中的每个服务任务的默认超时时间为500毫秒,我们将请求平均排队时间设置为20毫秒,以此作为服务器过载的标志。这种经验性的配置已经在
















