Overload Control for Scaling WeChat Microservices
0x00 引言
这篇Paper是微信的关于其后台过载控制系统。在微信这样复制的系统,错综复杂的系统依赖关系、难以准确估计的动态的实际负载水平。DAGOR系统使得微信的过载控制和服务逻辑分开。这个系统在微信后台中已经运行了5年,
... It manages overload at the microservice granule such that each microservice monitors its load status in real time and triggers load shedding in a collaborative manner among its relevant services when overload is detected. DAGOR has been used in the WeChat backend for five years.
0x01 背景
Paper中谈到了在复杂的微服务系统中过载控制系统面临诸多的挑战。这里主要谈了三个方面的问题,
- 所有的微服务都必须被监控到,如果存在监控的死角,可以这里形成的热点问题会级联影响到整个系统。在一个快速演化的系统中做到监控整个系统的状态是一件很困难的事情。
- 让微服务本身独立地处理过载可能是一个存在问题的方式。这个主要的原因是整个系统中微服务之间复杂的依赖关系。Paper中的例子很好地说明了这点:假设一个客户端的请求依赖于K个微服务,如果每个微服务由于过载控制拒绝这个请求的概率为p,这样的话这个请求能够完成的概率就是(1-p)^K。即使p很小,当K一大的时候,也会造成有比较大比例的客户端请求被拒绝。而且,部分完成的客户端请求是失败的,但是完成的部分依然会消耗后台服务的资源。
- 过载控制必须要能够适应系统负载的快速变化。
微信的后台是一个基于微服务的架构,基本的架构如下图所示。架构总体上面分为三层。微信的后台服务中运行了几千个的微服务。这里服务之间的依赖关系可以表示为DAG。总体上这里讲服务范围两类,一类是Basic Service,一类是Leap Service。
这里常见的过载的情况讨论了下面的三种,第一种在SOA中是常见的一种,后面两种在大规模的微服务系统中也会出现。Paper在这这里定义了Subsequent Overload。Subsequent Overload指的是存在被上流的服务调用多次的单个or多个微服务的情形。
Obviously, both Form 2 (in Figure 2.b) and Form 3 (in Figure 2.c) belong to subsequent overload. Subsequent overload in Form 2 is due to the consecutive invocations to the single overloaded service, whereas subsequent overload in Form 3 is caused by the separate invocations to different overloaded services.
多次调用带来的一个情况就是,在存在由于过载被拒绝调用的情况下,成功率的随着调用次数增多快速降低。一上面的Form2为例子,就是如果一个上流的调用有50%机会被拒绝的话,整个调用成功的几率就只有25%。在微信后台这样的大规模的微服务系统中:1. 一个请求存在很多的入口,一个调用经过的路径也会十分复杂,另外即使对于同样类型的调用,调用路径页不一定完全相同。这样的情况下,精确确定哪些种类的请求应该被拒绝时不可能的。2. 不合适的请求解决会浪费太多资源,
... Especially, the situation becomes severe when subsequent overload happens. This calls for some kind of coordination to manage load shedding properly, regarding the request type, priority, call path and service properties.
0x02 基本架构
对DAGOR有这样的几个基本的要求,1. Service Agnostic,DAGOR必须可以是适应各种的微服务情况,2. Independent but Collaborative,3. Efficient and Fair。DANOR主要的工作主要分为:Overload Detection 过载探测,Service Admission Contro 服务准入控制。 ####Overload Detection DAGOR使用去中心化的过载探测。在探测的指标上面,DAGOR使用平均的请求排队时间作为一个过载探测的指标。DAGOR认为,这个排队时间与响应时间相比,它一般只取决于本地的处理能力,而响应时间则取决于整个调用路径上面的情况。使用CPU利用率也不是一个很好的指标,只要是因为高的CPU负载页不一定就代表了过载的情况。和很多的监控系统一样,这里也是使用了基于时间窗口的机制,
In the WeChat business system, each server refreshes its monitoring status of the average request queuing time every second or every 2000 requests, whenever either criteria is met. Such compounded constraint ensures that the monitoring can immediately catch up with the load changes in spite of the workload dynamics.
Service Admission Control
这部分是这篇Paper最主要讲的一部分。DANOR使用两种基本的基于优先级的准入控制策略:面向业务的策略和面向用户的策略。然后在此基础上引入了自适应的策略和组合策略。
-
面向业务的策略。这种策略的基本出发点是不同的业务的重要性不同的,这样就可理解为这些业务对应了不同的优先级。比如登陆业显然会是高优先级的业务,不能让用户连登陆都不能操作。另外的一个例子就是微信支付的请求会高于即时消息发送请求的优先级,
The operation log of WeChat shows that when WeChat Pay and Instant Messaging experience a similar period of service unavailability, user’s complaint against the WeChat Pay service is 100 times more than that against the Instant Messaging service.
面向业务的策略就是给不同的业务不同的优先级。这个请求导致的其它请求也会继承这个优先级。一个负载出于过载的情况之后,服务会首先拒绝低优先级的请求。这些优先级的信息被保存到一个Hash表里面。一个服务请求下流的服务的时候,都会带上这个请求优先级的信息,这样的话,一个请求的请求路径上面都能够得到这个优先级的信息。这个优先级与具体的服务逻辑相关,很好地适应了对DAGOR这个系统的一些要求。
-
面向用户的策略。上面的基于业务的策略一个不能解决的问题就是部分拒绝(Partially Discarding)的问题。在Paper中以一个Admission Level变化的例子。这里引入了一个面向用户策略的方法。一个用户的请求会根据这个用户的ID计算出来一个Hash值,依次来确定这个请求的优先级。这个优先级的计算会是动态变化的。不过在一段时间之内(比如一个小时),这个用户请求的优先级基本是固定的。这里的策略配合基于业务的策略。下面的图是一个说明的例子,一个业务优先级中又被划分来用户优先级,
For requests with business priority equal to the admission level of business priority of the overloaded service, the corresponding load shedding operation gives priority to the ones with high user priority. By doing so, once a request from service A to the overloaded service M gets a successful response, the subsequent request from service A to service M is very likely to also get a successful response.
-
面向Session的Admission Contril也和面向用户的类似。它使用的是一个Session的优先级,基本策略也和面向用户的一样,只是优先级生产的方式基于Session ID。这个看起来和面向用户的策略是一样的,但是在实际的应用中,由于类似登出油例子登陆的行为导致来这个效果不是很好。
除了上面的基本的策略之外,还要以及基于基本的策略在优化改进的策略,
-
Adaptive Admission Control,这里基本的思路就是策略的组合使用,
... DAGOR uses the compound admission level which is composed of the business and user priorities. Each admission level of business priority is attached with 128 admission levels of user priority.
-
Collaborative Admission Control,这里的策略很有意思。这个方式很好地解决了复杂的大规模的微服务系统中,其中的少数的服务过载之后,它上流的服务可能还在继续请求这个服务。这样的话之前已经做的请求实际上就被浪费了。这里基本的思路就是下流的服务在响应上流服务请求的时候,带上自己的Admission Level的请求,让上流的服务避免一些调用一些很有可能被解决的请求。
Workflow of Overload Control
总结一下DAGOR中的过载控制的基本处理流程,
- 当一个用户的请求到达微服务系统的时候,被路由到对应的服务入口。这个入口服务会赋予这个请求一个业务和用户优先级。下面的请求就会继承这个优先级。这些信息会被作为请求信息的一部分被携带;
- 根据业务逻辑请求下流的服务;
- 一个微服务接受到一个请求的时候,先根据目前的Adminssion Level执行基于优先级的准入控制操作。这个Adimssion Level会根据实时的情况周期性地调整。当一个服务准备请求下流的服务时,它会根据下流的微服务的Admission Level执行本地的准入控制操作;
- 一个下流的服务恢复上流服务的请求之后,会带上它的Admission Level的信息;
- 上流的服务会根据请求响应携带的信息更新本地保存的其他服务Admission Level的信息;
0x03 评估
这里的详细信息可以参看[1].
参考
- Overload Control for Scaling WeChat Microservices, SoCC ‘18.