旅游网站的建设开题报告,桂林哪里可以做网站,网页传奇手机版,网站建设开发案例教程视频作者#xff1a;刘泉禄 整体介绍
本文所说的“柔性服务”主要是指 consumer 端的负载均衡和 provider 端的限流两个功能。在之前的 Dubbo 版本中#xff0c;负载均衡部分更多的考虑的是公平性原则#xff0c;即 consumer 端尽可能平等的从 provider 中作出选择#xff0c;… 作者刘泉禄 整体介绍
本文所说的“柔性服务”主要是指 consumer 端的负载均衡和 provider 端的限流两个功能。在之前的 Dubbo 版本中负载均衡部分更多的考虑的是公平性原则即 consumer 端尽可能平等的从 provider 中作出选择在某些情况下表现并不够理想。而限流部分只提供了静态的限流方案需要用户对 provider 端设置静态的最大并发值然而该值的合理选取对用户来讲并不容易。我们针对这些存在的问题进行了改进。
负载均衡
在原本的 Dubbo 版本中有五种负载均衡的方案供选择他们分别是 “Random” , “ShortestResponse” , “RoundRobin”“LeastActive” 和 “ConsistentHash”。
其中除 “ShortestResponse” 和 “LeastActive” 外其他的几种方案主要是考虑选择时的公平性和稳定性。对于 “ShortestResponse” 来说其设计目的是从所有备选的 provider 中选择 response 时间最短的以提高系统整体的吞吐量。然而存在两个问题 在大多数的场景下不同 provider 的 response 时长没有非常明显的区别此时该算法会退化为随机选择。 response 的时间长短有时也并不能代表机器的吞吐能力。对于 “LeastActive” 来说其认为应该将流量尽可能分配到当前并发处理任务较少的机器上。但是其同样存在和 “ShortestResponse” 类似的问题即这并不能单独代表机器的吞吐能力。
基于以上分析我们提出了两种新的负载均衡算法。一种是同样基于公平性考虑的单纯 “P2C” 算法另一种是基于自适应的方法 “adaptive”其试图自适应的衡量 provider 端机器的吞吐能力然后将流量尽可能分配到吞吐能力高的机器上以提高系统整体的性能。
效果介绍
对于负载均衡部分的有效性实验在两个不同的情况下进行的分别是提供端机器配置比较均衡和提供端机器配置差距较大的情况。 使用方法
使用方法与原本的负载均衡方法相同。只需要在 consumer 端将 “loadbalance” 设置为 “p2c” 或者 “adaptive” 即可。
代码结构
负载均衡部分的算法实现只需要在原本负载均衡框架内继承 LoadBalance 接口即可。
原理介绍
P2C 算法
Power of Two Choice 算法简单但是经典主要思路如下 对于每次调用从可用的 provider 列表中做两次随机选择选出两个节点 providerA 和 providerB。 比较 providerA 和 providerB 两个节点选择其“当前正在处理的连接数”较小的那个节点。
adaptive 算法
代码的 github 地址 [ 1]
相关指标
cpuLoad
cpuLoad cpu一分钟平均负载 * 100 / 可用cpu数量。该指标在 provider 端机器获得并通过 invocation 的 attachment 传递给 consumer 端。
rt
rt 为一次 rpc 调用所用的时间单位为毫秒。
timeout
timeout 为本次 rpc 调用超时剩余的时间单位为毫秒。
weight
weight 是设置的服务权重。
currentProviderTime
provider 端在计算 cpuLoad 时的时间单位是毫秒
currentTime
currentTime 为最后一次计算 load 时的时间初始化为 currentProviderTime单位是毫秒。
multiple
multiple(当前时间 - currentTime)/timeout 1
lastLatency beta
平滑参数默认为0.5
ewma
lastLatency 的平滑值
lastLatencybeta*lastLatency(1 - beta)*lastLatency
inflight
inflight 为 consumer 端还未返回的请求的数量。
inflightconsumerReq - consumerSuccess - errorReq
load
对于备选后端机器x来说若距离上次被调用的时间大于 2*timeout则其 load 值为 0。
否则
loadCpuLoad*(sqrt(ewma) 1)*(inflight 1)/(((consumerSuccess / (consumerReq 1) )*weight)1)
算法实现
依然是基于 P2C 算法。 从备选列表中做两次随机选择得到 providerA 和 providerB 比较 providerA 和 providerB 的 load 值选择较小的那个。
自适应限流
与负载均衡运行在 consumer 端不同的是限流功能运行在 provider 端。其作用是限制 provider 端处理并发任务时的最大数量。从理论上讲服务端机器的处理能力是存在上限的对于一台服务端机器当短时间内出现大量的请求调用时会导致处理不及时的请求积压使机器过载。在这种情况下可能导致两个问题
1.由于请求积压最终所有的请求都必须等待较长时间才能被处理从而使整个服务瘫痪。
2.服务端机器长时间的过载可能有宕机的风险。因此在可能存在过载风险时拒绝掉一部分请求反而是更好的选择。在之前的 Dubbo 版本中限流是通过在 provider 端设置静态的最大并发值实现的。但是在服务数量多拓扑复杂且处理能力会动态变化的局面下该值难以通过计算静态设置。
基于以上原因我们需要一种自适应的算法其可以动态调整服务端机器的最大并发值使其可以在保证机器不过载的前提下尽可能多的处理接收到的请求。
因此我们参考部分业界方案实现基础上在 Dubbo 的框架内实现了两种自适应限流算法分别是基于启发式平滑的 “HeuristicSmoothingFlowControl” 和基于窗口的 “AutoConcurrencyLimier”。
代码的 github 地址 [ 2]
效果介绍
自适应限流部分的有效性实验我们在提供端机器配置尽可能大的情况下进行并且为了凸显效果在实验中我们将单次请求的复杂度提高将超时时间尽可能设置的大并且开启消费端的重试功能。 使用方法
要确保服务端存在多个节点并且消费端开启重试策略的前提下限流功能才能更好的发挥作用。设置方法与静态的最大并发值设置类似只需在 provider 端将 “flowcontrol” 设置为 “autoConcurrencyLimier” 或者 “heuristicSmoothingFlowControl” 即可。
代码结构 FlowControlFilter在 provider 端的 filter 负责根据限流算法的结果来对 provider 端进行限流功能。 FlowControl根据 Dubbo 的 spi 实现的限流算法的接口。限流的具体实现算法需要继承自该接口并可以通过 Dubbo 的 spi 方式使用。 CpuUsage周期性获取 cpu 的相关指标 HardwareMetricsCollector获取硬件指标的相关方法 ServerMetricsCollector基于滑动窗口的获取限流需要的指标的相关方法。比如 qps 等。 AutoConcurrencyLimier自适应限流的具体实现算法。 HeuristicSmoothingFlowControl自适应限流的具体实现方法。
原理介绍
HeuristicSmoothingFlowControl
相关指标
alpha
alpha 为可接受的延时的上升幅度默认为 0.3
minLatency
在一个时间窗口内的最小的 Latency 值。
noLoadLatency
noLoadLatency 是单纯处理任务的延时不包括排队时间。这是服务端机器的固有属性但是并不是一成不变的。在 HeuristicSmoothingFlowControl 算法中我们根据机器CPU的使用率来确定机器当前的 noLoadLatency。当机器的 CPU 使用率较低时我们认为 minLatency 便是 noLoadLatency。当 CPU 使用率适中时我们平滑的用 minLatency 来更新 noLoadLatency 的值。当 CPU 使用率较高时noLoadLatency 的值不再改变。
maxQPS
一个时间窗口周期内的 QPS 的最大值。
avgLatency
一个时间窗口周期内的 Latency 的平均值单位为毫秒。
maxConcurrency
计算得到的当前服务提供端的最大并发值。
maxConcurrencyceil(maxQPS*((2 alpha)*noLoadLatency - avgLatency))
算法实现
当服务端收到一个请求时首先判断 CPU 的使用率是否超过 50%。如果没有超过 50%则接受这个请求进行处理。如果超过 50%说明当前的负载较高便从 HeuristicSmoothingFlowControl 算法中获得当前的 maxConcurrency 值。如果当前正在处理的请求数量超过了 maxConcurrency则拒绝该请求。
AutoConcurrencyLimier
相关指标
MaxExploreRatio
默认设置为 0.3
MinExploreRatio
默认设置为 0.06
SampleWindowSizeMs
采样窗口的时长。默认为 1000 毫秒。
MinSampleCount
采样窗口的最小请求数量。默认为 40。
MaxSampleCount
采样窗口的最大请求数量。默认为 500。
emaFactor
平滑处理参数。默认为 0.1。
exploreRatio
探索率。初始设置为 MaxExploreRatio。若 avgLatencynoLoadLatency*(1.0 MinExploreRatio) 或者 qpsmaxQPS*(1.0 MinExploreRatio)则 exploreRatiomin(MaxExploreRatio,exploreRatio0.02)
否则
exploreRatiomax(MinExploreRatio,exploreRatio-0.02)
maxQPS
窗口周期内 QPS 的最大值。 noLoadLatency halfSampleIntervalMs
半采样区间。默认为 25000 毫秒。
resetLatencyUs
下一次重置所有值的时间戳这里的重置包括窗口内值和 noLoadLatency。单位是微秒。初始为 0. remeasureStartUs
下一次重置窗口的开始时间。 startSampleTimeUs
开始采样的时间。单位为微秒。
sampleCount
当前采样窗口内请求的数量。
totalSampleUs
采样窗口内所有请求的 latency 的和。单位为微秒。
totalReqCount
采样窗口时间内所有请求的数量和。注意区别 sampleCount。
samplingTimeUs
采样当前请求的时间戳。单位为微秒。
latency
当前请求的 latency。
qps
在该时间窗口内的 qps 值。 avgLatency
窗口内的平均 latency。 maxConcurrency
上一个窗口计算得到当前周期的最大并发值。
nextMaxConcurrency
当前窗口计算出的下一个周期的最大并发值。 Little’s Law
当服务处于稳定状态时concurrencylatency*qps。这是自适应限流理论的基础。当请求没有导致机器超载时latency 基本稳定qps 和 concurrency 处于线性关系。当短时间内请求数量过多导致服务超载的时候concurrency 会和latency一起上升qps则会趋于稳定。
算法实现
AutoConcurrencyLimier 的算法使用过程和 HeuristicSmoothingFlowControl 类似。
实现与 HeuristicSmoothingFlowControl 的最大区别是 AutoConcurrencyLimier 是基于窗口的。每当窗口内积累了一定量的采样数据时才利用窗口内的数据来更新得到 maxConcurrency。
其次利用 exploreRatio 来对剩余的容量进行探索。
另外每隔一段时间都会自动缩小 max_concurrency 并持续一段时间以处理 noLoadLatency 上涨的情况。因为估计 noLoadLatency 时必须先让服务处于低负载的状态因此对 maxConcurrency 的缩小是难以避免的。
由于 max_concurrency
Dubbo 于上周上线了新版官网与文档涵盖 Dubbo3 核心功能及特性关于自适应负载均衡、自适应限流及更多方案的详细讲解请访问https://dubbo.apache.org
相关链接
[1] 代码的 github 地址
https://github.com/apache/dubbo/pull/10745
[2] 代码的 github 地址
https://github.com/apache/dubbo/pull/10642