SpringCloud系列之负载均衡Ribbon·11-IRule机制_抽象类 image.png

一、IRule接口

public interface IRule{
/*
* choose one alive server from lb.allServers or
* lb.upServers according to key
*
* @return choosen Server object. NULL is returned if none
* server is available
*/

public Server choose(Object key);

public void setLoadBalancer(ILoadBalancer lb);

public ILoadBalancer getLoadBalancer();
}

然后我们再找到RibbonClientConfiguration类,找到使用了IRule的方法:

@Bean
@ConditionalOnMissingBean
public IRule ribbonRule(IClientConfig config) {
if (this.propertiesFactory.isSet(IRule.class, name)) {
return this.propertiesFactory.get(IRule.class, config, name);
}
ZoneAvoidanceRule rule = new ZoneAvoidanceRule();
rule.initWithNiwsConfig(config);
return rule;
}

@Bean
@ConditionalOnMissingBean
public ILoadBalancer ribbonLoadBalancer(IClientConfig config,
ServerList<Server> serverList, ServerListFilter<Server> serverListFilter,
IRule rule, IPing ping, ServerListUpdater serverListUpdater) {
if (this.propertiesFactory.isSet(ILoadBalancer.class, name)) {
return this.propertiesFactory.get(ILoadBalancer.class, config, name);
}
return new ZoneAwareLoadBalancer<>(config, rule, ping, serverList,
serverListFilter, serverListUpdater);
}

可以看到在ribbonRule方法主要是返回一个IRule的ribbon策略,而在下面的方法则是获取到IRule,然后返回一个LoadBalancer。

然后我们可以在LoadBalancerInterceptor打上一个断点,然后查看Ribbon服务的调用链是如何的:


SpringCloud系列之负载均衡Ribbon·11-IRule机制_配置文件_02 image.png

把断点放掉可以发现,断点到了ribbonRule这个方法。


SpringCloud系列之负载均衡Ribbon·11-IRule机制_配置文件_03 image.png

SpringCloud系列之负载均衡Ribbon·11-IRule机制_抽象类_04 image.png

if条件中是 针对于 eureka-client 是否配置了一个IRule的策略,如果配置了一个策略,那么就获取到这个策略:

SpringCloud系列之负载均衡Ribbon·11-IRule机制_抽象类_05 image.png

然后我们就会发现NFLoadBalancerRuleClassName就是我们在配置文件中配置的信息:

eureka-client.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

而这个方法将返回配置信息中配置的类:com.netflix.loadbalancer.RandomRule

整个跟了一遍我们大概了解了ribbon的实现过程,那么如果我们需要扩展一个IRule就可以这么做:

可以新建一个类,然后实现IRule的抽象类即可。


SpringCloud系列之负载均衡Ribbon·11-IRule机制_.net_06 image.png