1、注入的方式
添加Bean
@Bean
public IRule getRule(){
return new RandomRule();
}
再次启动项目,发送请求,就是随机的了。
实现方式在这RibbonClientConfiguration中:
@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);
}
如果没有IRule,那么就使用默认的,不过先从propertiesFactory中找。
然后将IRule放入到ILoadBalancer中稍后使用。
从这里我们就能看出,第二种使用方式,那就是从propertiesFactory中获取。
2、配置方式
2.1实现
在RibbonAutoConfiguration中,注入了propertiesFactory
@Bean
@ConditionalOnMissingBean
public PropertiesFactory propertiesFactory() {
return new PropertiesFactory();
}
该类通过Spring的Environment获取配置:
public class PropertiesFactory {
@Autowired
private Environment environment;
private Map<Class, String> classToProperty = new HashMap<>();
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);
//environment.get("client.ribbon.NFLoadBalancerRuleClassName")
String className = environment
.getProperty(name + "." + NAMESPACE + "." + classNameProperty);
return className;
}
return null;
}
其中22行的name来自下面的配置,默认值是client,在使用过程中,会添加ribbon.client.name=对应的服务名
@RibbonClientName
private String name = "client";
@Value("${ribbon.client.name}")
public @interface RibbonClientName {
}
我们修改代码,也能看出,配置文件的优先级大于注入的方式。
2.2 使用
添加配置:
user-service:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
重启服务,测试通过。
3、总结
注解的方式是全局的,但是配置的方式只是针对某一个服务的。
4、懒加载
Ribbon默认是采用懒加载,即第一次访问时才会去创建请求服务的LoadBalanceClient,请求时间会很长。而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:
ribbon:
eager-load:
enabled: true
clients: #需要饥饿加载的服务
- user-service