0

We have about 50 microservices developed using Spring Boot. We use Spring Cloud for registering services with Eureka and invoke the service from the consumer using Feign. The contract is pretty standard, where the consumer uses an interface with @FeignClient("<foo>") annotation to locate a service that's registered as foo with Eureka. The registration, lookup and invocation on the target service all works as expected with one or multiple instances of the service running.

We have a new requirement where the same service foo may be running multiple instances where each instance has a specific stereotype or designation. For example, some instances of foo are expected to deal with 3rd party integration synchronous workload, and some instances of foo are expected to deal with internal messages (asynchronous workload). We have defined a configuration property called stereotype in the service that would be defined at the bootstrap (done via part of Spring Cloud config) to tell the service instance to deal with sync or async workloads. The configuration looks like this:

service.stereotype: sync # or async

In addition, we also add this property to the Eureka's eureka.instance.metadatamap map as stereotype property when registering the service foo. I can see that the Eureka now displays this value for service foo when it gets registered.

So far so good. Now the question:

Is there a configuration (or annotation) mechanism in either the DiscoveryClient or Feign to lookup foo but using the stereotype as a qualifier. In other words, when my consumer application looks up Eureka, can it somehow tell Eureka to give only the instance where, for example, the stereotype is async? If this is possible, then my consumer component can ensure that the asynchronous workload is only sent to the foo instance that deals with asynchronous workload.

So far, in my research, I have not found anything. I wrote a sample (that can possibly go in a DiscoveryClient override) that would use Eureka REST interface GET /eureka/v2/apps/appID as outlined here and then find the target endpoint by looking up the metadata map for each instance that's returned. But that sounded like brute force. I'd ideally like to do this using one of the existing mechanisms if available, so that I can continue using the load balancing and retry features of Feign instead of reinventing the wheel.

Kartik Pandya
  • 2,718
  • 2
  • 14
  • 28
  • Trying to approach it a different way... Why not register the service that deals with sync or async as two disparate service names in Eureka? Setup your application so that the `spring.application.name` is `foo-sync` or `foo-async`. Then the Feign client would just use that specific name to get the right instances? – Shawn Clark Aug 24 '16 at 06:27
  • That was the first thing that came to mind, but it doesn't work as the idea is not to have to hardcode the `stereotype` in the Feign client. That information is more environment specific and not something that's readily available at the time of development. It can definitely do what we need technically, but if there's a way to do it through environment specific configuration, that'd be ideal. – Kartik Pandya Aug 24 '16 at 14:25

0 Answers0