专注于Java、Golang、软件架构、项目管理

Back

ribbon的作用:一个服务部署多个实例时,负责负载均衡请求的组件

ribbon重要组件#

ILoadBalancer:负载均衡器,其中包含了IRule和IPing

IRule:负责负载均衡选择服务的规则

IPing:定时ping服务器,判断其是否存活

ribbon的入口#

@LoadBalanced将将一个RestTemplate标志为底层采用LoadBalancerClient来执行实际的http请求,支持负载均衡。

org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration中有相关的bean注册。LoadBalancerRequestFactory、LoadBalancerInterceptor、RestTemplateCustomizer等等

使用RestTemplateCustomizer对每个restTemplate,使用LoadBalancerInterceptor进行定制。

LoadBalancerClient是谁?#

LoadBalancerClient在org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration中进行注册了,RibbonLoadBalancerClient

需要注意的是,对于client来说,每个服务也可以说服务名对应一个独立的ApplicationContext。

@Bean
@ConditionalOnMissingBean(LoadBalancerClient.class)
public LoadBalancerClient loadBalancerClient(final SpringClientFactory springClientFactory) {
   return new RibbonLoadBalancerClient(springClientFactory);
}
java

那么LoadBalancerClient底层使用的ILoadBalancer是谁呢?#

org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration中有如下配置

	@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);
	}
java

ZoneAwareLoadBalancer与eureka整合,如何获取到注册表呢?#

其父类DynamicServerListLoadBalancer#initWithNiwsConfig方法

比较坑的是RibbonClientConfiguration和EurekaRibbonClientConfiguration都配置了serverlist

通过调试发现,还是DiscoveryEnabledNIWSServerList的getUpdatedServerList()方法返回的server list。此处估计是根据配置,使用各自的server

那么server list怎么更新服务列表呢?#

//RibbonClientConfiguration配置的
@Bean
@ConditionalOnMissingBean
public ServerListUpdater ribbonServerListUpdater(IClientConfig config) {
   return new PollingServerListUpdater(config);
}
java

默认一分钟过后第一次执行,然后每隔30秒执行一次,刷新注册表

//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;
}
java

默认的负载均衡为ZoneAvoidanceRule,其基类PredicateBasedRule的choose方法。

默认是轮询算法

RibbonLoadBalancerClient调用excute执行方法调用。其中重要的调用

最后ribbon的健康检查。调用对应服务的健康检查接口,进行判断