newhouse
newhouse

Reputation: 1282

Programmatically created Feign client and Eureka target

I have started a few days ago to learn about fault tolerance solutions in microservices. I have some microservices in my ecosystem and they are now interconnected with Eureka service lookup. I used FeignClient to call from one to another. As I heard and read, that Hystrix is getting into maintenance, I wondered if I could use Resilience4J in Feign instead of Hystrix. Well, at least not from annotation level right now as it seems. I found a great Feign.Builder adapter to add resilience4j fault tolerance features above a FeignClient as a decorator (https://github.com/resilience4j/resilience4j/tree/master/resilience4j-feign) so I wanted to use it.

So I used this, added together the features and added the default encoder, decoder, etc. items into the feign builder. Turns out I have to finish of course my code with a .target call which creates my client proxy and I could not really do this with Eureka in a good way:

  1. The first constructor, which takes the class type and the URL is hardcoded, so if I add an eureka next server query into this parameter, it is just a hardcoded url for one of the instances, this is not load balanced. Some kinda workaround could be that I create prototype-scope or similar short lived scoped beans of this client and always get the "next url" for the call. This adds lots of burden to use the clients in every class I make. At least as I saw it. Maybe I could add some kind of singleton helper bean around the prototyping, but again this is not a good design as I see

  2. I thought maybe I could create an EurekaTarget from the Target interface, but of course none of the methods indicate any "end of lifecycle" things, not even the apply method. I thought maybe that is one point which is called before doing a service call, but I saw multiple calls towards it so I had to change the url for all calls.

Do you know any better solution to do this migration?

Upvotes: 0

Views: 1642

Answers (1)

Robert Winkler
Robert Winkler

Reputation: 1907

I guess you are using Spring Boot? The next version v1.0.0 of Resilience4j will support the @FeignClient annotation. There was a PR which added the functionality -> https://github.com/resilience4j/resilience4j/pull/579

You can then use it as follows:

@FeignClient(name = DUMMY_FEIGN_CLIENT_NAME)
@CircuitBreaker(name = DUMMY_FEIGN_CLIENT_NAME)
public interface DummyFeignClient {

    String DUMMY_FEIGN_CLIENT_NAME = "dummyFeignClient";

    @GetMapping(path = "/api/{param}")
    void doSomething(@PathVariable(name = "param") String param);
} 

Upvotes: 2

Related Questions