Micronaut - Discovery Client and Client-side load balancing with Consul
Help Superheroes to get discovered

I am a developer who loves Java, Spring, Quarkus, Micronaut, Open source, Microservices, Cloud
Search for a command to run...
Help Superheroes to get discovered

I am a developer who loves Java, Spring, Quarkus, Micronaut, Open source, Microservices, Cloud
No comments yet. Be the first to comment.
Micronaut is one of the promising java based frameworks in the Microservices space. Here is a series that I have started on Microservices framework based on Micronaut.
Calling Super Heroes With Faker and Micronaut
Spring AI Tool Calling: From Chatbot to AI Agent with @Tool Your AI is smart. It knows an enormous amount. But it's frozen. It doesn't know what time it is right now. It doesn't know what's on your ca
Spring AI Advisors API Explained Series: Spring AI Complete Course — Lecture 4 of 12Reading Time: 8 minutesLevel: Intermediate Most developers stop at ChatClient. That is enough for demos. It is not
Working with Multiple AI Models in Spring AI Spring AI Complete Course — Lecture 3 of 12Previous: Lecture 2 — ChatClient API | Next: Lecture 4 — Advisors API In production AI applications, you rarel
Spring AI ChatClient API: The Fluent Heart of AI Integration Introduction If you've ever tried integrating AI models into a Java application, you know the pain. HTTP clients, API keys scattered everywhere, vendor-specific SDKs that never quite fit. W...
What is Spring AI? — Why Java Developers Need This in 2026 Every AI tutorial you see is in Python. LangChain, LlamaIndex, OpenAI SDK — all Python. But here's the uncomfortable truth: 80% of enterprise backends run Java. So who's building AI into thos...
In any microservice architecture, we need multiple instances of the services. Our superhero API is no different. While we have been running only one instance of superhero API and command center, it is far from reality.
In the real world, the load on servers is expected to increase. We need to establish efficient communication to talk between services.
Suppose, there is a surge in load, we need to increase the instances of superhero API, how will the command-center know the new instances URLs. How will it call them and balance the load on servers? Till now, we hardcoded it with the @Client annotation and value as URL.
Can we solve this problem if we have another service that can keep track of all the services deployed? If it can know all the instances of any service and can give us the URLs. How good it could be if we distribute the load among all available instances.
In this section we will solve this using Consul Service discovery and client-side load balancing.
@Client annotation to use id of the service rather URLsWhen we add this dependency and let client know that they have to register at consul service discovery, client will sent HTTP request at startup. it keeps sending the request at regular interval to let the consul service discovery app know that its up and running.

Add the below dependency to the superhero API and command center poms
<dependency>
<groupId>io.micronaut.discovery</groupId>
<artifactId>micronaut-discovery-client</artifactId>
<scope>compile</scope>
</dependency>
Once it is added, we will tell apps the address of the consul server so that they can register themselves.
Add the below in superhero and command-center application.yml
consul:
client:
registration:
enabled: true
defaultZone: "${CONSUL_HOST:localhost}:${CONSUL_PORT:8500}"
This will tell the application about the address of the consul server. At the start of microservices, they will hit the server on this port to let it know about their availability.
There are many ways to run consul, let us keep simple with docker, run below docker command to run it
docker run -p 8500:8500 consul
This will sun consul app and expose to 8500 port.
@Client annotation to use id of the service rather URLsTill now we have used hardcoded @Client value , let us use id rather than URL now. Ids are the same as Micronaut's application name .
We will update the declarative client used in the last section with id.
Below is the code
@Client(id = "superHeroes")
@Header(name = "Accept", value = HEADER_ACCEPT)
public interface SuperheroClient {
@Get("/rx/superheroes")
Flux<Superhero> superheroes();
@Get("/rx/superhero/{id}")
Mono<Superhero> superheroesById(Long id);
@Post("/rx/superhero")
Publisher<Superhero> create( @Body Superhero superhero);
@Put("/rx/superhero")
Publisher<Superhero> update( Superhero superhero);
@Delete("/rx/superhero/{id}")
Publisher<HttpResponse<Long>> delete(Long id);
}
If you observe we have updated @Client with id of superhero API. Whenever a call to superhero API is made, it can select one of the instances that have registered itself at consul.
Once it is all done , it's time to test the setup. To do that let us start multiple instance on superhero API. We can start them by directly invoking jar in the target folder and passing micronaut.server.port={PORT_NO} as parameter.
Open two terminals and navingate to project. Change directory to target folder and run the command
java -jar .\super-heroes-0.1.jar --micronaut.server.port=8082
java -jar .\super-heroes-0.1.jar --micronaut.server.port=8081
The above commands will start two instances of superhero API at 8081 and 8082 port. You will notice the application will register itself with consul and log it.


Once command-center all is up and you can see it registered to consul, you can verify all of them are at consul UI too. visit http://localhost:8500 where docker is running the consul

If you hit the API via command-center, You can see logs are different console widows of superhero API.
This shows the working load balancing of HttpClient with consul.