`
m635674608
  • 浏览: 5041944 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Netflix源码解析之Ribbon:负载均衡策略的定义和实现

 
阅读更多

Ribbon负载均衡策略定义

 

IRule其实就只做了一件事情Server choose(Object key),可以看到这个功能是在LB中定义(要求)的,LB把这个功能委托给IRule来实现。不同的IRule可以向LB提供不同的负载均衡算法。

 

publicinterfaceIRule{publicServer choose(Object key);publicvoid setLoadBalancer(ILoadBalancer lb);publicILoadBalancer getLoadBalancer();}

 

com.netflix.loadbalancer包下面的提供了常用的几种策略。有RoundRobinRule、RandomRule这样的不依赖于Server运行状况的策略,也有AvailabilityFilteringRule、WeightedResponseTimeRule等多种基于收集到的Server运行状况决策的策略。判断运行状况时有,判断单个server的,也有判断整个zone的,适用于各种不同场景需求。

 

实现上有些策略可以继承一个既存的简单策略用于某些启动时候,也可以包含一个简单策略。甚至有ZoneAvoidanceRule这样的可以包含复合谓词的条件判断。
IRule_implementation

 

Ribbon自带负载均衡策略比较

 

策略名 策略声明 策略描述 实现说明
BestAvailableRule ?public class BestAvailableRule extends ClientConfigEnabledRoundRobinRule 选择一个最小的并发请求的server 逐个考察Server,如果Server被tripped了,则忽略,在选择其中ActiveRequestsCount最小的server
AvailabilityFilteringRule ?public class AvailabilityFilteringRule extends PredicateBasedRule 过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值) 使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个server的运行状态
WeightedResponseTimeRule ?public class WeightedResponseTimeRule extends RoundRobinRule 根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。 一个后台线程定期的从status里面读取评价响应时间,为每个server计算一个weight。Weight的计算也比较简单responsetime 减去每个server自己平均的responsetime是server的权重。当刚开始运行,没有形成statas时,使用roubine策略选择server。
RetryRule public class RetryRule extends AbstractLoadBalancerRule 对选定的负载均衡策略机上重试机制。 在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server
RoundRobinRule ?public class RoundRobinRule extends AbstractLoadBalancerRule roundRobin方式轮询选择server 轮询index,选择index对应位置的server
RandomRule ?public class RandomRule extends AbstractLoadBalancerRule 随机选择一个server 在index上随机,选择index对应位置的server
ZoneAvoidanceRule public class ZoneAvoidanceRule extends PredicateBasedRule 复合判断server所在区域的性能和server的可用性选择server 使用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个server,前一个判断判定一个zone的运行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate用于过滤掉连接数过多的Server。

 

?Ribbon自带负载均衡策略实现解析

 

1. com.netflix.loadbalancer.BestAvailableRule
功能: 选择一个最小的并发请求的server
主要代码: 逐个考察Server,如果Server被tripped了,则忽略,在选择其中ActiveRequestsCount最小的server

 

for(Server server: serverList){ServerStats serverStats = loadBalancerStats.getSingleServerStat(server);if(!serverStats.isCircuitBreakerTripped(currentTime)){int concurrentConnections = serverStats.getActiveRequestsCount(currentTime);if(concurrentConnections < minimalConcurrentConnections){
minimalConcurrentConnections = concurrentConnections;
chosen = server;}}

 

2 com.netflix.loadbalancer.AvailabilityFilteringRule
功能: 过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值)
主要代码 :使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个server的运行状态,过滤掉那些高并发的的后端server(active connections 超过配置的阈值)

 

boolean com.netflix.loadbalancer.AvailabilityPredicate.shouldSkipServer(ServerStats stats){if((CIRCUIT_BREAKER_FILTERING.get()&& stats.isCircuitBreakerTripped())|| stats.getActiveRequestsCount()>= activeConnectionsLimit.get()){returntrue;}returnfalse;}

 

3 com.netflix.loadbalancer.WeightedResponseTimeRule

 

功能: 根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。 ”
主要代码: 一个后台线程定期的从status里面读取评价响应时间,为每个server计算一个weight。Weight的计算也比较简单responsetime 减去每个server自己平均的responsetime是server的权重。当刚开始运行,没有形成statas时,使用roubine策略选择server。

 

classDynamicServerWeightTaskextendsTimerTask{publicvoid run(){ServerWeight serverWeight =newServerWeight();
serverWeight.maintainWeights();}}

maintainWeights(){List<Double> finalWeights =newArrayList<Double>();for(Server server : nlb.getAllServers()){ServerStats ss = stats.getSingleServerStat(server);double weight = totalResponseTime  ss.getResponseTimeAvg();
weightSoFar += weight;
finalWeights.add(weightSoFar);}
setWeights(finalWeights);}Server choose(ILoadBalancer lb,Object key){double randomWeight = random.nextDouble()* maxTotalWeight;// pick the server index based on the randomIndexint n =0;for(Double d : currentWeights){if(d >= randomWeight){
serverIndex = n;break;}else{
n++;}}

server = allList.get(serverIndex);}

 

4 com.netflix.loadbalancer.RetryRule

 

功能: 对选定的负载均衡策略机上重试机制。
主要代码: 在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server

 

answer = subRule.choose(key);if(((answer ==null)||(!answer.isAlive()))&&(System.currentTimeMillis()< deadline)){InterruptTask task =newInterruptTask(deadline -System.currentTimeMillis());while(!Thread.interrupted()){
answer = subRule.choose(key);if(((answer ==null)||(!answer.isAlive()))&&(System.currentTimeMillis()< deadline)){/* pause and retry hoping it’s transient */Thread.yield();}else{break;}}
task.cancel();

 

5 com.netflix.loadbalancer.RoundRobinRule

 

功能: roundRobin方式轮询选择server
主要代码: 轮询index,选择index对应位置的server

 

List<Server> allServers = lb.getAllServers();int upCount = reachableServers.size();int serverCount = allServers.size();int nextServerIndex = incrementAndGetModulo(serverCount);
server = allServers.get(nextServerIndex);

 

6 com.netflix.loadbalancer.RandomRule

 

功能: 随机选择一个server
主要代码: 在index上随机,选择index对应位置的server

 

List<Server> upList = lb.getReachableServers();List<Server> allList = lb.getAllServers();int serverCount = allList.size();int index = rand.nextInt(serverCount);
server = upList.get(index);

 

7 com.netflix.loadbalancer.ZoneAvoidanceRule

 

功能: 复合判断server所在区域的性能和server的可用性选择server
主要代码: 使用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个server,前一个,以一个区域为单位考察可用性,对于不可用的区域整个丢弃,从剩下区域中选可用的server。判断出最差的区域,排除掉最差区域。在剩下的区域中,将按照服务器实例数的概率抽样法选择,从而判断判定一个zone的运行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate用于过滤掉连接数过多的Server。

 

public com.netflix.loadbalancer.PredicateBasedRule.Server choose(Object key){ILoadBalancer lb = getLoadBalancer();Optional<Server> server = getPredicate().chooseRoundRobinAfterFiltering(lb.getAllServers(), key);if(server.isPresent()){return server.get();}}

 

参照现有的若干中rule的实现风格,根据我们自己需要也可以开发出自定义的负载均衡策略。

 

完。

 

 

原创文章。为了维护文章的版本一致、最新、可追溯,转载请注明: 转载自 idouba

本文链接地址: Netflix源码解析之Ribbon:负载均衡策略的定义和实现

 

分享到:
评论

相关推荐

    spring-cloud-netflix源码

    《Spring Cloud Netflix源码解析》 Spring Cloud Netflix是Spring Cloud框架的一个重要组成部分,它提供了微服务架构中的多种功能,如服务发现、断路器、智能路由等。在深入理解Spring Cloud Netflix之前,我们先要...

    cloud2020.zip--周阳老师源码

    源码展示了如何在服务中启用Hystrix,定义熔断策略,以及监控和展示熔断状态。通过Hystrix Dashboard,我们可以实时查看服务间的调用情况和熔断状态。 4. Zuul:作为API网关,它负责所有外部请求的统一入口,实现了...

    SpringCloudTutorial-master.zip

    5. **负载均衡**:通过Ribbon配置客户端负载均衡策略,观察服务调用时如何选择不同的服务实例。 6. **配置管理**:了解如何使用Spring Cloud Config服务器,配置微服务的动态更新,体验配置的实时生效。 7. **总线...

    springcloud项目

    Ribbon是Netflix提供的一个客户端负载均衡器,它与Eureka结合使用,自动从服务注册中心获取服务列表,并进行负载均衡,使得请求能够均匀地分发到各个服务实例。 6. **Feign:声明式HTTP客户端** Feign是基于Java...

    springCloud

    使用Feign,只需要创建一个接口并注解,它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解,Feign支持可插拔的编码器和解码器,Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。 Feign ...

    spring-cloud-matser课程源码-01.rar

    4. **负载均衡**:Ribbon是Spring Cloud内置的客户端负载均衡器,与Eureka结合使用,可以在服务调用时实现客户端的负载均衡。源码会展示如何在服务消费者中集成Ribbon,实现对服务实例的智能选择。 5. **断路器模式...

    <>源代码

    2. **负载均衡**:Ribbon是Netflix提供的一个客户端负载均衡器,与Eureka结合,可以在服务调用时自动选择合适的服务器。源代码中会包含Ribbon的配置和使用,例如定义ClientRule策略。 3. **断路器**:Hystrix是...

    SpringCloud学习笔记(十)声明式客户端Feign的简单调用 源码包

    - **负载均衡**: Feign内置了Ribbon,可以自动进行客户端负载均衡,选择合适的服务器进行请求。 - **断路器**: 结合Hystrix,Feign可以实现熔断和降级策略,提高系统的容错性。 2. **Feign使用步骤** - **创建...

    Eureka简介与Eureka Server-代码部分.zip

    - Eureka是由Netflix开发的服务发现组件,基于RESTful API设计,用于在分布式系统中定位服务,以实现云端的负载均衡和中间层服务器的故障切换。 - Eureka由两部分组成:Eureka Server(服务注册中心)和Eureka ...

    springcloud学习源码-yuanma.zip

    源码中可以查看负载均衡策略的实现。 7. **Spring Cloud OpenFeign**:声明式Web服务客户端,简化了服务之间的调用。源码分析有助于理解如何通过注解定义接口,并自动创建HTTP客户端。 8. **Spring Cloud Gateway*...

    Spring cloud 的Greenwich版本 完整文档,文档中包括了源码

    4. **负载均衡**:Ribbon是Netflix提供的客户端负载均衡器,而Spring Cloud Loadbalancer是Spring Cloud提供的更现代的解决方案。文档会解释如何在微服务间实现负载均衡。 5. **断路器模式**:Hystrix是Netflix的...

    spring cloud zuul 使用

    - 负载均衡:集成Ribbon或Eureka,实现对后端服务的负载均衡。 - 安全控制:可以通过过滤器实现身份验证、访问控制等安全策略。 - 监控:可以记录请求日志,提供请求统计信息,便于系统监控和问题排查。 - 过滤...

    SpringCloud-OpenSource-Analysis:SpringCloud组件源码分析

    在源码层面,我们可以学习Ribbon如何根据Eureka获取服务实例列表,以及它如何根据负载均衡策略选择目标服务实例。 5. **Feign**:Feign是一个声明式Web服务客户端,简化了服务间的调用。它通过注解定义接口,自动...

    reactive.loanbroker.system:使用Spring Reactive Web,Project Reactor和Spring Cloud Netflix Stack开发的贷款经纪人系统

    Spring Cloud Netflix是Spring Cloud的一个子项目,它包含了一系列微服务架构相关的组件,如Eureka(服务发现)、Zuul(边缘服务/API网关)、Hystrix(断路器)、 Ribbon(客户端负载均衡器)等。在本项目中,这些...

Global site tag (gtag.js) - Google Analytics