spring cloud默认的LoadBalancerClient是RibbonLoadBalancerClient

介绍

背景

在编写简单的Spring Cloud示例中,使用自动注入的BalancerClient访问注册中心的实例(instance)。
项目参考:https://blog.csdn.net/BS0003/article/details/110000862中的eureka-registry-consumer-original子模块

好奇之下,想要了解LoadBalancerClient的默认实现。

过程

查看源码,有两个实现了LoadBalancerClient的类

  1. org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient
  2. org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient

在eureka-registry-consumer-original中,将Ribbon的依赖jar从项目去除。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </exclusion>
    </exclusions>
</dependency>

启动项目报错。
错误提示

***************************
APPLICATION FAILED TO START
***************************

Description:

Field loadBalancerClient in com.chyong.ribbon.ContentFromCenterController required a bean of type 'org.springframework.cloud.client.loadbalancer.LoadBalancerClient' that could not be found.

The injection point has the following annotations:
	- @org.springframework.beans.factory.annotation.Autowired(required=true)

The following candidates were found but could not be injected:
	- Bean method 'blockingLoadBalancerClient' in 'BlockingLoadBalancerClientAutoConfiguration.BlockingLoadbalancerClientConfig' not loaded because AnyNestedCondition 0 matched 2 did not; NestedCondition on OnNoRibbonDefaultCondition.RibbonLoadBalancerNotPresent @ConditionalOnMissingClass found unwanted class 'org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient'; NestedCondition on OnNoRibbonDefaultCondition.RibbonNotEnabled @ConditionalOnProperty (spring.cloud.loadbalancer.ribbon.enabled=false) did not find property 'spring.cloud.loadbalancer.ribbon.enabled'
	- Bean method 'loadBalancerClient' in 'RibbonAutoConfiguration' not loaded because AllNestedConditions 3 matched 1 did not; NestedCondition on RibbonAutoConfiguration.RibbonClassesConditions.RibbonPresent @ConditionalOnClass did not find required class 'com.netflix.ribbon.Ribbon'; NestedCondition on RibbonAutoConfiguration.RibbonClassesConditions.AsyncRestTemplatePresent @ConditionalOnClass found required class 'org.springframework.web.client.AsyncRestTemplate'; NestedCondition on RibbonAutoConfiguration.RibbonClassesConditions.RestTemplatePresent @ConditionalOnClass found required class 'org.springframework.web.client.RestTemplate'; NestedCondition on RibbonAutoConfiguration.RibbonClassesConditions.IClientPresent @ConditionalOnClass found required class 'com.netflix.client.IClient'

根据错误提示(读起来费劲),跟踪源码(手动,电脑不行)
大体的意思:
LoadBalancerClient注入失败。原因BlockingLoadbalancerClientConfig.blockingLoadBalancerClient没有加载,原因是@Conditional(OnNoRibbonDefaultCondition.class)失败

@Conditional(OnNoRibbonDefaultCondition.class)
protected static class BlockingLoadbalancerClientConfig {...}

接着看OnNoRibbonDefaultCondition类源码,错误提示是

NestedCondition on OnNoRibbonDefaultCondition.RibbonNotEnabled @ConditionalOnProperty (spring.cloud.loadbalancer.ribbon.enabled=false) did not find property 'spring.cloud.loadbalancer.ribbon.enabled'

发现这里说找不到’spring.cloud.loadbalancer.ribbon.enabled’属性
在eureka-registry-consumer-original项目的yml中添加

spring:
  cloud:
    loadbalancer:
      ribbon:
        enabled: false

重新启动,成功。

总结

  1. LoadBalancerClient的默认实现是RibbonLoadBalancerClient
  2. 如果项目中没有RibbonLoadBalancerClient,那么需要在yml中添加以上的配置,从而可以让BlockingLoadBalancerClient生效。

对源码的了解还是一知半解。还写下以后需要再补充。


版权声明:本文为BS0003原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。