使用Springcloud Loadbalancer集成Openfeign报错

使用Springcloud Loadbalancer集成Openfeign报错
报错内容

No qualifying bean of type 'org.springframework.cloud.client.discovery.ReactiveDiscoveryClient' available

application.yml配置文件

server:
  port: 8080
spring:
  application:
    name: consumer-01
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        namespace: c7ffbcd1-c4d8-425b-b41c-a1077693fa57
        group: A_GROUP
    loadbalancer:
      ribbon:
        enabled: false
      nacos:
        enabled: true
      enabled: true
      configurations: zone-preference
      zone: zone1
        hint:
        default: myhint

主类

@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
public class Consumer01Application {

    public static void main(String[] args) {
        SpringApplication.run(Consumer01Application.class, args);
    }
}

Openfeign controller(前端调用这个接口)

@RestController
public class OpenFeignController {

    @Autowired
    private FeignEchoService echoService;

    @GetMapping("/feign/echo/{message}")
    public String feignEcho(@PathVariable String message) {
        return echoService.echo(message);
    }
}

FeignEchoService配置,我的服务是provider-01,有三个实例

@LoadBalancerClient(name = "provider-01", configuration = CustomLoadBalancerConfig.class)
@FeignClient(value = "provider-01") // 指向服务提供者应用
public interface FeignEchoService {
    @LoadBalanced
    @GetMapping("/echo/{message}")
    String echo(@PathVariable("message") String message);
}

自定义的负载均衡配置,添加下面这个bean就会报错,不添加就正常运行,但是这样我没办法配置zone和hint

public class CustomLoadBalancerConfig {
    // 随机负载均衡
    @Bean
    ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }

    // 配置zone
    @Bean
    public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(ConfigurableApplicationContext context) {
        return ServiceInstanceListSupplier.builder().withDiscoveryClient().withZonePreference().withCaching().build(context);
    }
}

provider-01的application.yml

server:
  port: 8081
spring:
  application:
    name: provider-01
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        namespace: c7ffbcd1-c4d8-425b-b41c-a1077693fa57
        group: A_GROUP
        metadata:
          zone: zone1
          hint: myhint
    loadbalancer:
      ribbon:
        enabled: false
      nacos:
        enabled: false
      enabled: true
      configurations: zone-preference

provider-01的controller

@RestController
public class EchoServiceController {

    @GetMapping("/echo/{message}")
    public String echo(@PathVariable String message) {
        return message;
    }
}

DiscoveryClientReactiveDiscoveryClient 代表服务消费者Consumer从注册中心发现服务提供者Provider的服务发现操作。两个接口的差异就体现在getServices()getInstances(String serviceId)。只是把List类型转换成了Reactor里的Flux类型。Springcloud 默认使用的是DiscoveryClient,在Spring WebFlux场景下,ReactiveDiscoveryClient才会生效,所以需要添加webflux依赖。

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

该回答引用ChatGPT-3.5,仅为您提供参考,不保证完全正确
根据您提供的信息,您遇到的问题是在将Spring Cloud LoadBalancer集成到OpenFeign中时,出现了"No qualifying bean of type 'org.springframework.cloud.client.discovery.ReactiveDiscoveryClient' available"的错误。这个错误通常发生在没有配置DiscoveryClient的情况下,因为Spring Cloud LoadBalancer需要DiscoveryClient来获取服务实例信息。


要解决这个问题,您可以尝试以下步骤:

  1. 添加Spring Cloud Discovery依赖:确保您的项目中包含Spring Cloud Discovery的依赖,例如Spring Cloud Netflix Eureka或Spring Cloud Alibaba Nacos等,根据您的实际使用情况选择。

  2. 配置DiscoveryClient:在您的项目配置文件中,确保已正确配置DiscoveryClient,以便Spring Cloud LoadBalancer可以使用它来获取服务实例信息。例如,如果您使用Nacos作为服务注册中心,您的配置应该如下:

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        namespace: c7ffbcd1-c4d8-425b-b41c-a1077693fa57
        group: A_GROUP
  1. 确保@EnableDiscoveryClient注解:确保您的主类上使用了@EnableDiscoveryClient注解,以启用服务发现功能。

  2. 检查依赖版本:确保您的Spring Cloud和Spring Cloud LoadBalancer的版本与您的Spring Boot版本兼容。不同版本之间可能存在不兼容性问题。

  3. 清除Maven或Gradle缓存:有时,依赖冲突或缓存问题可能导致奇怪的错误。尝试清除Maven或Gradle缓存,然后重新构建项目。

如果您仍然遇到问题,请提供更多详细信息,以便更好地帮助您解决问题。您还可以查看应用程序的日志,以获取更多关于错误的信息,这可能有助于确定问题的根本原因。


该回答引用NewBing,仅为您提供参考,不保证完全正确
根据我搜索到的结果,您可能需要做以下几个步骤:

  • 确保您的pom.xml文件中包含了spring-cloud-starter-loadbalancer和spring-cloud-starter-openfeign的依赖¹²。
  • 确保您的application.yml文件中关闭了ribbon.enabled和nacos.enabled的配置²³。
  • 确保您的LoadBalancer配置类中只有一个ServiceInstanceListSupplier的bean,而不是两个⁴。您可以参考这个示例²来配置Spring Cloud LoadBalancer和SpringCloudOpenFeign。
  • 确保您的FeignClient接口中不使用@LoadBalanced注解,因为这是用于RestTemplate的,而不是FeignClient¹。

源: 与必应的对话, 2023/9/7
(1) java.lang.IllegalStateException: No Feign Client for loadBalancing .... https://stackoverflow.com/questions/63702885/java-lang-illegalstateexception-no-feign-client-for-loadbalancing-defined-did.
(2) How to configure Spring Cloud LoadBalancer with SpringCloudOpenFeign. https://stackoverflow.com/questions/70623493/how-to-configure-spring-cloud-loadbalancer-with-springcloudopenfeign.
(3) Error: Load balancer does not contain an instance for the service while .... https://stackoverflow.com/questions/67777620/error-load-balancer-does-not-contain-an-instance-for-the-service-while-using-sp.
(4) spring - Load balancer does not contain an instance for the service .... https://stackoverflow.com/questions/67953892/load-balancer-does-not-contain-an-instance-for-the-service.


该回答引用文心一言,仅为您提供参考,不保证完全正确
超出输入上限(2000)


该回答引用讯飞星火,仅为您提供参考,不保证完全正确
报错的原因是在CustomLoadBalancerConfig类中,没有定义zonehint的bean。你可以尝试将zonehint的配置添加到discoveryClientServiceInstanceListSupplier方法中,如下所示:

@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(ConfigurableApplicationContext context) {
    return ServiceInstanceListSupplier.builder()
            .withDiscoveryClient()
            .withZonePreference()
            .withCaching()
            .filter(instance -> instance.getMetadata().get("zone") != null && instance.getMetadata().get("hint") != null)
            .build(context);
}

这样,当创建ServiceInstanceListSupplier时,会过滤出包含zonehint的实例。

【相关推荐】



  • 这篇博客: 【云原生&微服务十四】SpringCloud之深度源码剖析OpenFeign如何为FeignClient生成动态代理类中的 1> LoadBalancerFeignClient在哪里注入到Spring容器? 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:

    进入到LoadBalancerFeignClient类中,看哪里调用了它唯一一个构造函数;
    在这里插入图片描述

    找到LoadBalancerFeignClient发现有三个地方调用了它的构造函数,new了一个实例;

    • DefaultFeignLoadBalancedConfiguration
    • HttpClientFeignLoadBalancedConfiguration
    • OkHttpFeignLoadBalancedConfiguration

    再结合默认的配置,只有DefaultFeignLoadBalancedConfiguration中的Client符合条件装配;

    在这里插入图片描述
    可以通过引入Apache HttpClient的maven依赖使用HttpClientFeignLoadBalancedConfiguration,

    或引入OkHttpClient的maven依赖并在application.yml文件中指定feign.okhttp.enabled属性为true使用OkHttpFeignLoadBalancedConfiguration。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^