Ribbon负载均衡_ribbon如何重写负载均衡
目录
一、负载均衡实现逻辑
二、负载均衡策略
三、修改负载均衡规则
四、饥饿加载
注:Ribbon拦截Eureka请求,找eureka-server拿对应服务信息,根据对应策略返回调用的ip和端口。
一、负载均衡实现逻辑
1、逻辑图
2、ClientHttpRequestInterceptor接口:客户端http请求拦截
3、LoadBalancerInterceptor类实现上面接口
//该方法拦截http请求@Overridepublic ClientHttpResponse intercept(final HttpRequest request,final byte[] body,final ClientHttpRequestExecution execution){//得到请求地址:http://user-service/user/1final URI originalUri = request.getURI();//得到服务名user-serviceString serciceName=originalUri.getHost();//RibbonLoadBalancerClient loadBalancer 进入负载均衡客户端return this.loadBalancer.execute(serviceName,this.requestFactory.createRequest(request,body,execution));}
4、RibbonLoadBalancerClient类
public T execute(String serviceId,LoadBalancerRequest request,Object hint) throws IOException{//根据服务名拿到服务信息 DynamicServerListLoadBalancer 动态服务列表负载均衡器ILoadBalancer loadBalancer=getLoadBalancer(serviceId);//根据指定策略获取具体服务IP端口Server server=getServer(loadBalancer,hint);if(server==null){ throw new IllegalStateException(\"No instances available for\"+serviceId);} RibbonServer ribbonServer=new RibbonServer(serviceId,server,isSecure(server,serviceId),serverIntrospector(serviceId).getMetadata(server)); return execute(serviceId,ribbonServer,request);}protected Server getServer(ILoadBalancer loadBalancer,Object hint){if(loadBalancer==null){return null;}return loadBalancer.chooseServer(hint!=null?hint:\"default\");}
5、ZoneAwareLoadBalancer类
@Overridepublic Server chooseServer(Object key){if(!ENABLED.get()||getLoadBalancerStats().getAvailableZones().size()<=1){logger.debug(\"Zone aware logic disabled or there is only one zone\");return super.chooseServer(key);}Server server=null;try{LoadBalancerStats lbStats=getLoadBalancerStats();}}
6、BaseLoadBalancer类
public Server chooseServer(Object key){if(counter==null){counter=createCounter();}counter.increment();if(rule==null){return null;}else{try{//调用IRule规则的实现类得到ip端口return rule.choose(key);}catch(Exception e){logger.warn(\"LoadBalancer [{}]: Error choosing server for key {}\",name,key,e);return null;}}}
二、负载均衡策略
Ribbon的负载均衡规则是一个叫做IRule的接口来定义的,每一个接口都是一种规则。
1、IRule层级(Eureka的实现类)
- AbstractLoadBalancerRule:策略抽象类1. RetryRule:重试,重试机制的选择逻辑。2. ClientConfigEnabledRoundRobinRule:- BestAvailableRule:最低并发,忽略哪些短路的服务器,并选择并发数较低的服务器。- PredicateBasedRule:- AvailabilityFilteringRule:可用过滤,[[#AvailabilityFilteringRule作用]]- ZoneAvoidanceRule:区域权重,[[#ZoneAvoidanceRule作用]]3. RoundRobinRule:轮询,简单轮询服务列表来选择服务器。它是Ribbon默认的负载均衡规则。- WeightedResponseTimeRule:[[#WeightedResponseTimeRule作用]]4. RandomRule:随机,随机选择一个可用的服务器。
2、AvailabilityFilteringRule作用
对以下两种服务器进行忽略:
-
在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为\"短路\"状态。短路状态将持续30秒,如果再次连接失败,短路的持续时间就会几何级地增加。
-
并发数过高的服务器。如果一个服务器的并发连接数过高,配置了AvailabilityFilteringRule规则的客户端也会将其忽略。并发连接数的上限,可以由客户端的..ActiveConnectionsLimit属性进行配置。
3、ZoneAvoidanceRule作用
-
以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房,一个机架等。而后再对Zone内的多个服务做轮询。
4、WeightedResponseTimeRule作用
-
为每一个服务器赋予一个权重值。服务器响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择。
三、修改负载均衡规则
1、引入依赖包
//eureka-ribbon 负载均衡 implementation \'org.springframework.cloud:spring-cloud-starter-netflix-ribbon:2.2.10.RELEASE\'
2、代码方式:在order-service中的OrderApplication类中,定义一个新的IRule
@Bean public IRule randomRule() { return new RandomRule(); }
3、 配置文件方式:在order-service的application.yml文件中,添加新的配置也可以修改规则
user-service: ribbon: # eureka负载均衡规则 NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule# nacos负载均衡规则 # NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
4、nacos的ribbon策略实现类
四、饥饿加载
-
Ribbon默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,请求时间会很长。而饥饿加载则会在项目启动时创建,降低第一次访问的耗时。
-
开启饥饿加载
ribbon: eager-load: # 开启饥饿加载 enabled: true clients: # 指定饥饿加载的服务名称 - user-service