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这样的可以包含复合谓词的条件判断。
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框架的一个重要组成部分,它提供了微服务架构中的多种功能,如服务发现、断路器、智能路由等。在深入理解Spring Cloud Netflix之前,我们先要...
源码展示了如何在服务中启用Hystrix,定义熔断策略,以及监控和展示熔断状态。通过Hystrix Dashboard,我们可以实时查看服务间的调用情况和熔断状态。 4. Zuul:作为API网关,它负责所有外部请求的统一入口,实现了...
5. **负载均衡**:通过Ribbon配置客户端负载均衡策略,观察服务调用时如何选择不同的服务实例。 6. **配置管理**:了解如何使用Spring Cloud Config服务器,配置微服务的动态更新,体验配置的实时生效。 7. **总线...
Ribbon是Netflix提供的一个客户端负载均衡器,它与Eureka结合使用,自动从服务注册中心获取服务列表,并进行负载均衡,使得请求能够均匀地分发到各个服务实例。 6. **Feign:声明式HTTP客户端** Feign是基于Java...
使用Feign,只需要创建一个接口并注解,它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解,Feign支持可插拔的编码器和解码器,Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。 Feign ...
4. **负载均衡**:Ribbon是Spring Cloud内置的客户端负载均衡器,与Eureka结合使用,可以在服务调用时实现客户端的负载均衡。源码会展示如何在服务消费者中集成Ribbon,实现对服务实例的智能选择。 5. **断路器模式...
2. **负载均衡**:Ribbon是Netflix提供的一个客户端负载均衡器,与Eureka结合,可以在服务调用时自动选择合适的服务器。源代码中会包含Ribbon的配置和使用,例如定义ClientRule策略。 3. **断路器**:Hystrix是...
- **负载均衡**: Feign内置了Ribbon,可以自动进行客户端负载均衡,选择合适的服务器进行请求。 - **断路器**: 结合Hystrix,Feign可以实现熔断和降级策略,提高系统的容错性。 2. **Feign使用步骤** - **创建...
- Eureka是由Netflix开发的服务发现组件,基于RESTful API设计,用于在分布式系统中定位服务,以实现云端的负载均衡和中间层服务器的故障切换。 - Eureka由两部分组成:Eureka Server(服务注册中心)和Eureka ...
源码中可以查看负载均衡策略的实现。 7. **Spring Cloud OpenFeign**:声明式Web服务客户端,简化了服务之间的调用。源码分析有助于理解如何通过注解定义接口,并自动创建HTTP客户端。 8. **Spring Cloud Gateway*...
4. **负载均衡**:Ribbon是Netflix提供的客户端负载均衡器,而Spring Cloud Loadbalancer是Spring Cloud提供的更现代的解决方案。文档会解释如何在微服务间实现负载均衡。 5. **断路器模式**:Hystrix是Netflix的...
- 负载均衡:集成Ribbon或Eureka,实现对后端服务的负载均衡。 - 安全控制:可以通过过滤器实现身份验证、访问控制等安全策略。 - 监控:可以记录请求日志,提供请求统计信息,便于系统监控和问题排查。 - 过滤...
在源码层面,我们可以学习Ribbon如何根据Eureka获取服务实例列表,以及它如何根据负载均衡策略选择目标服务实例。 5. **Feign**:Feign是一个声明式Web服务客户端,简化了服务间的调用。它通过注解定义接口,自动...
Spring Cloud Netflix是Spring Cloud的一个子项目,它包含了一系列微服务架构相关的组件,如Eureka(服务发现)、Zuul(边缘服务/API网关)、Hystrix(断路器)、 Ribbon(客户端负载均衡器)等。在本项目中,这些...