做承诺的网站,鹤壁网站建设,专业做英文网站,酷站 网站负载均衡策略与配置细节
Dubbo 内置了 client-based 负载均衡机制#xff0c;如下是当前支持的负载均衡算法#xff0c;结合上文提到的自动服务发现机制#xff0c;消费端会自动使用 Weighted Random LoadBalance 加权随机负载均衡策略 选址调用。
如果要调整负载均衡算法…负载均衡策略与配置细节
Dubbo 内置了 client-based 负载均衡机制如下是当前支持的负载均衡算法结合上文提到的自动服务发现机制消费端会自动使用 Weighted Random LoadBalance 加权随机负载均衡策略 选址调用。
如果要调整负载均衡算法以下是 Dubbo 框架内置的负载均衡策略
算法特性备注配置值Weighted Random LoadBalance加权随机默认算法默认权重相同random (默认)RoundRobin LoadBalance加权轮询借鉴于 Nginx 的平滑加权轮询算法默认权重相同roundrobinLeastActive LoadBalance最少活跃优先 加权随机背后是能者多劳的思想leastactiveShortest-Response LoadBalance最短响应优先 加权随机更加关注响应速度shortestresponseConsistentHash LoadBalance一致性哈希确定的入参确定的提供者适用于有状态请求consistenthashP2C LoadBalancePower of Two Choice随机选择两个节点后继续选择“连接数”较小的那个节点。p2cAdaptive LoadBalance自适应负载均衡在 P2C 算法基础上选择二者中 load 最小的那个节点adaptive
全局配置
Dubbo 框架的默认策略是 random 加权随机负载均衡。如果要调整策略只需要设置 loadbalance 相应取值即可每种负载均衡策略取值请参见文档最上方表格。
为所有服务调用指定全局配置
dubbo:consumer:loadbalance: roundrobin接口级配置
可以为每个服务指定不同的负载均衡策略。
在 provider 端设置作为 consumer 侧默认值
DubboService(loadbalance roundrobin)
public class DemoServiceImpl implements DemoService {}在 consumer 端设置具备更高优先级
DubboReference(loadbalance roundrobin)
private DemoService demoService;方法级配置
也可以指定方法(method)级别的负载均衡策略。
在 Spring Boot 开发模式下配置 method 级别参数有以下几种方式
JavaConfig
Configuration
public class DubboConfiguration {Beanpublic ServiceBean demoService() {MethodConfig method new MethodConfig();method.setName(sayHello);method.setLoadbalance(roundrobin);ServiceBean service new ServiceBean();service.setInterface(DemoService.class);service.setRef(new DemoServiceImpl());service.addMethod(method)return service;}
}Autowire
private DemoService demoService;Configuration
public class DubboConfiguration {Beanpublic ReferenceBean demoService() {MethodConfig method new MethodConfig();method.setName(sayHello);method.setLoadbalance(roundrobin);ReferenceBeanDemoService reference new ReferenceBean();reference.setInterface(DemoService.class);reference.addMethod(method);return reference;}
}dubbo.properties
dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.loadbalanceroundrobin一致性哈希配置
默认采用第一个参数作为哈希 key如果需要切换参数可以指定 hash.arguments 属性
ReferenceConfigDemoService referenceConfig new ReferenceConfigDemoService();
// ... init
MapString, String parameters new HashMapString, String();
parameters.put(hash.arguments, 1);
parameters.put(sayHello.hash.arguments, 0,1);
referenceConfig.setParameters(parameters);
referenceConfig.setLoadBalance(consistenthash);
referenceConfig.get();自适应负载均衡配置
只需要在 consumer 或 provider 端将 loadbalance 设置为 p2c 或者 adaptive 即可。
自适应负载均衡与限流整体介绍
本文所说的柔性服务主要是指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 端机器的吞吐能力然后将流量尽可能分配到吞吐能力高的机器上以提高系统整体的性能。
总体效果
对于负载均衡部分的有效性实验在两个不同的情况下进行的分别是提供端机器配置比较均衡和提供端机器配置差距较大的情况。 使用方法
Dubbo Java 实现的使用方法 与原本的负载均衡方法相同。只需要在consumer端将loadbalance设置为p2c或者adaptive即可。
代码结构
负载均衡部分的算法实现只需要在原本负载均衡框架内继承 LoadBalance接口即可。
原理介绍
P2C算法
Power of Two Choice 算法简单但是经典主要思路如下
对于每次调用从可用的provider列表中做两次随机选择选出两个节点providerA和providerB。比较providerA和providerB两个节点选择其“当前正在处理的连接数”较小的那个节点。
adaptive算法
代码的github地址
相关指标 cpuLoad 。该指标在provider端机器获得并通过invocation的attachment传递给consumer端。 rt rt为一次rpc调用所用的时间单位为毫秒。 timeout timeout为本次rpc调用超时剩余的时间单位为毫秒。 weight weight是设置的服务权重。 currentProviderTime provider端在计算cpuLoad时的时间单位是毫秒 currentTime currentTime为最后一次计算load时的时间初始化为currentProviderTime单位是毫秒。 multiple lastLatency beta 平滑参数默认为0.5 ewma lastLatency的平滑值 inflight inflight为consumer端还未返回的请求的数量。 load 对于备选后端机器x来说若距离上次被调用的时间大于2*timeout则其load值为0。 否则,
算法实现
依然是基于P2C算法。
从备选列表中做两次随机选择得到providerA和providerB比较providerA和providerB的load值选择较小的那个。
自适应限流
与负载均衡运行在consumer端不同的是限流功能运行在provider端。其作用是限制provider端处理并发任务时的最大数量。从理论上讲服务端机器的处理能力是存在上限的对于一台服务端机器当短时间内出现大量的请求调用时会导致处理不及时的请求积压使机器过载。在这种情况下可能导致两个问题
由于请求积压最终所有的请求都必须等待较长时间才能被处理从而使整个服务瘫痪。服务端机器长时间的过载可能有宕机的风险。
因此在可能存在过载风险时拒绝掉一部分请求反而是更好的选择。在之前的 Dubbo 版本中限流是通过在 provider 端设置静态的最大并发值实现的。但是在服务数量多拓扑复杂且处理能力会动态变化的局面下该值难以通过计算静态设置。
基于以上原因我们需要一种自适应的算法其可以动态调整服务端机器的最大并发值使其可以在保证机器不过载的前提下尽可能多的处理接收到的请求。因此我们参考相关理论与算法实践基础上在 Dubbo 框架内实现了两种自适应限流算法分别是基于启发式平滑的HeuristicSmoothingFlowControl 和基于窗口的 AutoConcurrencyLimier。
代码的github地址
使用介绍
总体效果
自适应限流部分的有效性实验我们在提供端机器配置尽可能大的情况下进行并且为了凸显效果在实验中我们将单次请求的复杂度提高将超时时间尽可能设置的大并且开启消费端的重试功能。 使用方法
要确保服务端存在多个节点并且消费端开启重试策略的前提下限流功能才能更好的发挥作用。
Dubbo Java 实现的自适应限流开启方法 与静态的最大并发值设置类似只需在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 计算得到的当前服务提供端的最大并发值。
算法实现
当服务端收到一个请求时首先判断CPU的使用率是否超过50%。如果没有超过50%则接受这个请求进行处理。如果超过50%说明当前的负载较高便从HeuristicSmoothingFlowControl算法中获得当前的maxConcurrency值。如果当前正在处理的请求数量超过了maxConcurrency则拒绝该请求。