【问题标题】:How to Disable Ribbon and just use FeignClient in Spring Cloud如何在 Spring Cloud 中禁用 Ribbon 并仅使用 FeignClient
【发布时间】:2018-09-20 02:43:04
【问题描述】:

我知道我们可以通过提供 url Ex 来强制 FeignClient 使用 OkHttp 而不是 Ribbon。 @FeignClient(url="serviceId", name="serviceId")

即使只提供了名称,我也希望使用 OkHttpClient。前任。 @FeignClient(name="serviceId")

根据 Spring Cloud 文档“如果启用了 Ribbon,则它是 LoadBalancerFeignClient,否则使用默认的 feign 客户端。”

如何禁用功能区以便使用默认的 feign 客户端。

【问题讨论】:

  • ribbon 是一个负载均衡器,我们不使用它的 http 客户端,所以我有点困惑。你可以用丝带 OkHttp。这就是你想要的吗?
  • Netflix FeignClient 默认会寻找负载均衡器。我想在没有负载均衡器的情况下使用 OkHttp。我可以通过在@feignClient 注释中提供 url 和 name 属性来实现这一点。但我想知道是否可以通过在@feignclient 注释中提供 name 属性来实现相同的目标。
  • 只使用名称将始终使用负载均衡器
  • 所以即使功能区不在类路径上,它仍然会寻找负载均衡器。正确的?是否可以通过某种解决方法覆盖该行为?
  • 如果功能区不在类路径上,那么 url 来自哪里?

标签: spring-cloud spring-cloud-netflix netflix-feign spring-cloud-feign feign


【解决方案1】:

互联网上的解决方案都不适合我。

  1. 只需在 url 部分设置绝对 url 就会导致负载平衡异常
// this resulted in java.lang.RuntimeException: com.netflix.client.ClientException: Load balancer does not have available server for client: localhost

@Lazy
@Configuration
@Import(FeignClientsConfiguration.class)
public class MyConfig {

    @LocalServerPort
    private int port;

    @Bean
    public MyClient myClient(final Decoder decoder, final Encoder encoder, final Client client) {
        return Feign.builder().client(client)
            .encoder(encoder)
            .decoder(decoder)
            .target(MyClient.class, "http://localhost:" + localServerPort);
    }
}
  1. 设置spring.cloud.loadbalancing.ribbon.enabled=false 导致应用程序上下文问题。需要禁用其他设置才能使其正常工作。我没有进一步探究
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'eurekaLoadBalancerClientConfiguration': Invocation of init method failed; nested exception is java.lang.NullPointerException

    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:160)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:416)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1788)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595)
...
...

我的工作解决方案

最后,在查看org.springframework.cloud.openfeign.ribbon.DefaultFeignLoadBalancedConfiguration中的源代码后,我想出了这个解决方案

@Lazy // required for @LocalServerPort to work in a @Configuration/@TestConfiguration
@TestConfiguration
@Import(FeignClientsConfiguration.class)
public class MyConfig {

    @LocalServerPort
    private int port;

    @Bean
    public MyClient myClient(Decoder decoder, Encoder encoder, Client client, Contract contract) {
        return Feign.builder().client(client)
            .encoder(encoder)
            .decoder(decoder)
            .contract(contract)
            .target(MyClient.class, "http://localhost:" + localServerPort);
    }

    // provide a default `FeignClient` so that Spring will not automatically create their LoadBalancingFeignClient
    @Bean
    public Client feignClient(SpringClientFactory clientFactory) {
        return new Client.Default(null, null);
    }
}

【讨论】:

    【解决方案2】:

    它与 Ribbon 无关。

    检查一下:

    feign:
      httpclient:
        enabled: false
    

    这将禁用 spring cloud 自动配置的 httpclient,并将在上下文中搜索名为 httpClient@Bean。所以在@Configuration 类中提供@Bean 的定义,仅此而已。

    在spring cloud feign中查看类FeignAutoConfiguration

    https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-feign.html

    【讨论】:

      【解决方案3】:

      我有同样的问题,但我的设置有点不同,我没有让它在我的情况下工作(使用带有 spring mvc 样式注释的 spring-cloud-starter-openfeign)。


      仅供参考:我需要一个带有 SSLSocketFactory 的自定义客户端,最后只为客户端创建了 bean 并将 URL 保留在 @FeignClient

       @Bean
       public Client myClient() {
           return new Client.Default(getSSLSocketFactory(), new NoopHostnameVerifier());
       }
      

      但是,我们确实有使用 spring-cloud-starter-feign 的项目,其中没有在注释上提供 URL。不确定下面的配置是否完整(我没有设置),但它可能会为您指明正确的方向...

      依赖项

      compile("org.springframework.cloud:spring-cloud-starter-feign") {
          exclude group: 'org.springframework.cloud', module: 'spring-cloud-starter-ribbon'
          exclude group: 'org.springframework.cloud', module: 'spring-cloud-starter-archaius'
      }
      

      配置

      @Configuration
      @Import(FeignClientsConfiguration.class) // org.springframework.cloud.netflix.feign.FeignClientsConfiguration
      public class MyConfig {
      
          @Value("${client.url}")
          private String url;    
      
          @Bean
          public MyClient myClient(final Decoder decoder, final Encoder encoder, final Client client) {
              return Feign.builder().client(client)
                  .encoder(encoder)
                  .decoder(decoder)
                  .target(MyClient.class, url);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2016-12-30
        • 2020-02-28
        • 2016-12-12
        • 2015-02-21
        • 2020-10-19
        • 2022-10-19
        • 2019-09-18
        • 2019-07-30
        • 2020-09-06
        相关资源
        最近更新 更多