0

I am trying to use @FeignClient for the first time in a simple REST client test application. I want to make use of Ribbon for the load balancing between two server instances, but not use Eureka. Following the documentation I have configured my application.yml with the listOfServers property and disabled Eureka. My client is named with the same name as the YAML prefix for the ribbon properties.

application.yml:

ds:
  ribbon:
    listOfServers: server1:18201,server2:18201

Client code:

@FeignClient("ds")
public interface DataServicesClient {
  @RequestMapping(method = RequestMethod.GET, value = "/context-path/customers")
  List<Customers> getCustomers();
}

When I invoke the application, I can see the listOfServers being picked up by Ribbon:

2016-03-07 12:15:17.275  INFO 39948 --- [nio-8081-exec-1] 
    c.n.l.DynamicServerListLoadBalancer      : DynamicServerListLoadBalancer for client ds 
    initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=ds,current list of 
    Servers=[server1:18201, server2:18201]

However the client then makes a call using only the value of the @RequestMapping annotation without the server prefix, and obviously fails.

2016-03-07 12:15:21.394 ERROR 39948 --- [nio-8081-exec-1] o.a.c.c.C.[.[.[/].
    [dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context 
    with path [] threw exception [Request processing failed; nested exception is 
    feign.RetryableException: Unexpected end of file from server executing GET 
    http://context-path/customers] with root cause
java.net.SocketException: Unexpected end of file from server
at sun.net.www.http.HttpClient.parseHTTPHeader(Unknown Source)

I was expecting it to inject each server in turn (http:{server instance}/context-path/customers), so I obviously have missed something here.

Can anyone please point me in the right direction?

Thanks,

Rob.

Ben Klein
  • 1,719
  • 3
  • 18
  • 41
RobP
  • 706
  • 1
  • 8
  • 20
  • 1
    It works for me. Can you share a simple sample project? – Dave Syer Mar 07 '16 at 14:31
  • Thanks Dave. It appears I was expecting too much of the Annotation/Autowiring. I have resolved the issue by creating my client via a Feign.builder() rather than autowiring an instance of @FeignClient, and then telling the builder to use the RibbonClient i.e.: 'DataServicesClient api = Feign.builder().contract(new SpringMvcContract()).client(new RibbonClient()).target( DataServicesClient.class, "https://ds")' – RobP Mar 07 '16 at 15:14
  • 1
    Fine, but you shouldn't have to do that. `@EnableFeignClients` will do exactly that for you. – Dave Syer Mar 07 '16 at 15:40
  • Hmm ok that would be better as the change would be less invasive. Let me sanitize and share my example project then. – RobP Mar 07 '16 at 15:43

1 Answers1

1

So it turns our that the problem was I was trying to access a secured resource but hadn't prefixed my feign client with https.

@FeignClient("https://ds")

I may be somewhat naive but I didn't find the error really explained the issue too well:

java.net.SocketException: Unexpected end of file from server

I was also expecting the selected server instance to be present in the error message, but looks like we just get the client name. This let me to believe the server was simply omitted, but I guess that's just part of the learning curve.

Anyway, the problem has now been resolved and its working with just the @EnableFeignClients annotation, no need for the Feign.builder().

Thanks for the support @Dave Syer

RobP
  • 706
  • 1
  • 8
  • 20