1
votes

Environment

  • Spring Boot 1.5.13.RELEASE
  • Spring Cloud Edgware.SR3
  • Java 8

Configuration

  • Eureka client is enabled and working correctly (I have tested and everything's working as I expect).

Some relevant properties from my configuration:

feign.hystrix.enabled=true
eureka.client.fetch-registry=true
spring.cloud.service-registry.auto-registration.enabled=true
service1.ribbon.listOfServers=https://www.google.com

Context

I have an application which speaks to 3 other services using feign clients. Two of these are discovered via Eureka service discovery. These are working well. The final service is an external one with a single static hostname and I do not want this resolved via Eureka. Since I do want Eureka for 2 of these services I would like to keep Eureka enabled.

Question

For the final service I tried adding service1.ribbon.listOfServers=https://www.google.com to the application.properties, however this cases the following error at runtime when invoking the feign client:

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is com.netflix.hystrix.exception.HystrixRuntimeException: Service1Client#test() failed and no fallback available.] with root cause pricing_1 | pricing_1 | com.netflix.client.ClientException: Load balancer does not have available server for client: service1 pricing_1 | at com.netflix.loadbalancer.LoadBalancerContext.getServerFromLoadBalancer(LoadBalancerContext.java:483) ~[ribbon-loadbalancer-2.2.5.jar!/:2.2.5]

My client is configured as follows:

@FeignClient("service1")
public interface Service1Client {

    @GetMapping(value = "/")
    String test();

}

Thanks in advance for any advice.

Consideration

Since the spirit of Ribbon as I understand it is to act as a client side load balancer and given in my case there is nothing to load balance (I have one fixed static hostname that returns a single A record in DNS). Ribbon actually feels like an unnecessary component - what I really wanted was the Feign client as I like the fact that it abstracts away the lower level HTTP request and object seralization. So I suppose an alternative follow up question is, can I use feign without ribbon - it seems the nice out of the box behaviour would be to use ribbon - even the Javadoc of the @FeignClient annotation says:

If ribbon is available it will be used to load balance the backend requests, and the load balancer can be configured using a @RibbonClient with the same name (i.e. value) as the feign client.

suggesting the two are quite closely related even if they are serving different purposes.

1

1 Answers

7
votes

As you mentioned, there are two ways to solve your problem.

Use Feign without Ribbon If you specify url attribute in @FeignClient annotation, it will work without Ribbon like the below.

@FeignClient(name = "service1", url = http://www.google.com)
public interface Service1Client {
    @GetMapping(value = "/")
    String test();
}

In this case, your other two Feign client will still work with Ribbon and Eureka.

Use Feign with Ribbon and without Eureka

What you are missing is in your configuration is NIWSServerListClassName. Its default value is com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList and it will use Eureka to retrieve the list of server. If you set NIWSServerListClassName to ConfigurationBasedServerList for a ribbon client (feign client), only that client will work with listOfServers list without retrieving server list from Eureka. And other feign clients will still work with Eureka.

service1:
  ribbon:
    NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
    listOfServers: http://www.google.com