Ribbon - 负载均衡流程提过了propertiesFactory.isSet,这个主要是用于修改某个服务的负载均衡。spring
@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; }
调用isSet的时候,会判断getClassName是否有找到对应的配置文件,若是有,则使用配置文件对应的规则。segmentfault
public PropertiesFactory() { classToProperty.put(ILoadBalancer.class, "NFLoadBalancerClassName"); classToProperty.put(IPing.class, "NFLoadBalancerPingClassName"); classToProperty.put(IRule.class, "NFLoadBalancerRuleClassName"); classToProperty.put(ServerList.class, "NIWSServerListClassName"); classToProperty.put(ServerListFilter.class, "NIWSServerListFilterClassName"); } public boolean isSet(Class clazz, String name) { return StringUtils.hasText(getClassName(clazz, name)); } public String getClassName(Class clazz, String name) { if (this.classToProperty.containsKey(clazz)) { String classNameProperty = this.classToProperty.get(clazz); String className = environment .getProperty(name + "." + NAMESPACE + "." + classNameProperty); return className; } return null; }
我本地的配置,这样就把轮询改成随机了。负载均衡
eureka-provider: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
首先要写一个@Configurable,里面包含了对应要重写的规则。这个@Configurable不能被spring扫描到。dom
@Configurable public class CustomerConfiguration { // 定义负载均衡策略 @Bean public IRule ribbonRule() { return new RandomRule(); } }
而后在ConsumerApplication(也能够在其余能被扫描的地方)加上@RibbonClient注解。@RibbonClient(value = "eureka-provider", configuration = a.b.c.CustomerConfiguration.class)。
启动后,对于eureka-provider的负载均衡策略,就是RandomRule。
那为何CustomerConfiguration不能扫描呢,Ribbon - 负载均衡流程中提过整个流程,这边针对这个CustomerConfiguration被扫描的状况下大概讲一下。ide
@RibbonClients(defaultConfiguration= a.b.c.CustomerConfiguration.class),经过RibbonClients注解配置全局。
Ribbon - 初始化提过@RibbonClients的处理,他会经过RibbonClientConfigurationRegistrar把@RibbonClients的配置最终保存在SpringClientFactory中,而后AnnotationConfigApplicationContext调用refresh的时候,就会注入CustomerConfiguration,而后加载咱们自定义的IRule等其余bean信息。this