整体介绍
Apache Dubbo
本文所说的“柔性服务”主要是指 consumer 端的负载均衡和 provider 端的限流两个功能。在之前的 Dubbo 版本中,负载均衡部分更多的考虑的是公平性原则,即 consumer 端尽可能平等的从 provider 中作出选择,在某些情况下表现并不够理想。而限流部分只提供了静态的限流方案,需要用户对 provider 端设置静态的最大并发值,然而该值的合理选取对用户来讲并不容易。我们针对这些存在的问题进行了改进。
自适应负载均衡
Apache Dubbo
在原本的 Dubbo 版本中,有五种负载均衡的方案供选择,他们分别是 "Random" , "ShortestResponse" , "RoundRobin","LeastActive" 和 "ConsistentHash"。
其中除 "ShortestResponse" 和 "LeastActive" 外,其他的几种方案主要是考虑选择时的公平性和稳定性。对于 "ShortestResponse" 来说,其设计目的是从所有备选的 provider 中选择 response 时间最短的以提高系统整体的吞吐量。然而存在两个问题:
1. 在大多数的场景下,不同 provider 的 response 时长没有非常明显的区别,此时该算法会退化为随机选择。
2. response 的时间长短有时也并不能代表机器的吞吐能力。对于 "LeastActive" 来说,其认为应该将流量尽可能分配到当前并发处理任务较少的机器上。但是其同样存在和 "ShortestResponse" 类似的问题,即这并不能单独代表机器的吞吐能力。


P2C 算法
1. 对于每次调用,从可用的 provider 列表中做两次随机选择,选出两个节点 providerA 和 providerB。
adaptive 算法
相关指标
1. cpuLoad
cpuLoad = cpu一分钟平均负载 * 100 / 可用cpu数量。该指标在 provider 端机器获得,并通过 invocation 的 attachment 传递给 consumer 端。
2. rt
3. timeout
4. weight
5. currentProviderTime
6. currentTime
7. multiple
multiple=(当前时间 - currentTime)/timeout + 1
8. lastLatency
9. beta
10. ewma
lastLatency 的平滑值
lastLatency=beta*lastLatency+(1 - beta)*lastLatency
11. inflight
inflight 为 consumer 端还未返回的请求的数量。
inflight=consumerReq - consumerSuccess - errorReq
12. load
否则
算法实现
1. 从备选列表中做两次随机选择,得到 providerA 和 providerB
自适应限流
Apache Dubbo
与负载均衡运行在 consumer 端不同的是,限流功能运行在 provider 端。其作用是限制 provider 端处理并发任务时的最大数量。从理论上讲,服务端机器的处理能力是存在上限的,对于一台服务端机器,当短时间内出现大量的请求调用时,会导致处理不及时的请求积压,使机器过载。在这种情况下可能导致两个问题:
1.由于请求积压,最终所有的请求都必须等待较长时间才能被处理,从而使整个服务瘫痪。
2.服务端机器长时间的过载可能有宕机的风险。因此,在可能存在过载风险时,拒绝掉一部分请求反而是更好的选择。在之前的 Dubbo 版本中,限流是通过在 provider 端设置静态的最大并发值实现的。但是在服务数量多,拓扑复杂且处理能力会动态变化的局面下,该值难以通过计算静态设置。
因此,我们参考部分业界方案实现基础上,在 Dubbo 的框架内实现了两种自适应限流算法,分别是基于启发式平滑的 "HeuristicSmoothingFlowControl" 和基于窗口的 "AutoConcurrencyLimier"。

1. FlowControlFilter:在 provider 端的 filter 负责根据限流算法的结果来对 provider 端进行限流功能。
2. FlowControl:根据 Dubbo 的 spi 实现的限流算法的接口。限流的具体实现算法需要继承自该接口并可以通过 Dubbo 的 spi 方式使用。
3. CpuUsage:周期性获取 cpu 的相关指标
4. HardwareMetricsCollector:获取硬件指标的相关方法
5. ServerMetricsCollector:基于滑动窗口的获取限流需要的指标的相关方法。比如 qps 等。
6. AutoConcurrencyLimier:自适应限流的具体实现算法。
HeuristicSmoothingFlowControl
相关指标
1. alpha
2. minLatency
3. noLoadLatency
4. maxQPS
5. avgLatency
6. maxConcurrency
计算得到的当前服务提供端的最大并发值。
算法实现
AutoConcurrencyLimier
相关指标
1. MaxExploreRatio
2. MinExploreRatio
3. SampleWindowSizeMs
4. MinSampleCount
5. MaxSampleCount
6. emaFactor
7. exploreRatio
否则
8. maxQPS
10. halfSampleIntervalMs
11. resetLatencyUs
12. remeasureStartUs
13. startSampleTimeUs
14. sampleCount
15. totalSampleUs
16. totalReqCount
17. samplingTimeUs
18. latency
19. qps
20. avgLatency
21. maxConcurrency
22. nextMaxConcurrency
Little's Law
算法实现
Dubbo 于上周上线了新版官网与文档,涵盖 Dubbo3 核心功能及特性,关于自适应负载均衡、自适应限流及更多方案的详细讲解,请访问:https://dubbo.apache.org
相关链接
Aliware
[1] 代码的 github 地址
[2] 代码的 github 地址
本文分享自微信公众号 - Apache Dubbo(ApacheDubbo)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。