Search code examples
spring-cloudspring-cloud-netflixnetflix-feignnetflix-ribbon

Unable to configure @FeignClient with list of servers


I am unable to configure a @FeignClient with a list of servers to use. I am using Spring Cloud Netflix, but this particular service (foo-service) does not register with Eureka. For this reason I need to configure a list of servers, for foo-service in a YML file.

However, the listOfServers is never read, and so the operation fails as Feign/Ribbon does not have a single server to use.

What am I doing wrong here?

My Feign client:

@FeignClient(name="foo-service")
public interface FooFeignClient {

   @RequestMapping(value = "/perform-check", method = POST)
   ResponseEntity<FooResponse> performCheck(FooRequest fooRequest);

}

In bootstrap.yml:

foo-service:
   ribbon:
      eureka:
         enabled: false
      listOfServers: foobox1,foobox2,foobox3

How the Feign client is configured in the Spring Boot application:

@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@EnableHazelcastClient
@EnableFeignClients
@RibbonClients({
   @RibbonClient(name = "foo-service", configuration = MyApp.FooServiceRibbonConfig.class)
})
public class MyApp {

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

   ....

   @Configuration
   static class FooServiceRibbonConfig {

      @Bean
      @ConditionalOnMissingBean
      public IClientConfig ribbonClientConfig() {
         DefaultClientConfigImpl config = new DefaultClientConfigImpl();
         config.loadProperties("foo-service");
         return config;
      }

      @Bean
      ServerList<Server> ribbonServerList(IClientConfig config) {
         ConfigurationBasedServerList serverList = new ConfigurationBasedServerList();
         serverList.initWithNiwsConfig(config);
         return serverList;
      }
   }
}

Solution

  • The easiest way to achieve your needs is..

    In your code, remove all code related to FooServiceRibbonConfig like below.

    @SpringBootApplication
    @EnableEurekaClient
    @EnableDiscoveryClient
    @EnableHazelcastClient
    @EnableFeignClients
    })
    public class MyApp {
    
       public static void main(String[] args) {
          SpringApplication.run(MyApp.class, args);
       }
       ....
    }
    

    And then change your profile files like below.

    foo-service:
       ribbon:
          NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
          listOfServers: foobox1,foobox2,foobox3
    

    Defining ribbonServerList bean like you did is another way to achieve that, and I'm not sure why your code is not running. In my case, similar code like yours works well. But there is a easier way, so please try it.