Service discovery in Spring Boot (Spring Cloud + Netflix Eureka)
- 4.6/5
- 5614
- Jul 20, 2024
In this article, we will see how to use Netflix Eureka as a discovery service for microservices based on Spring Cloud and Spring BOOT.
We will also see how to register microservices with Netflix Eureka using Spring Cloud and how a client can use Spring Cloud LoadBalancer to send HTTP requests to one of the instances registered in Netflix Eureka.
Netflix Eureka provides client-side service discovery, that means the clients run code that talks to the discovery server, Netflix Eureka, to get information about the available microservice instances.
How does a Netflix Eureka-based service discovery function?
When a microservice instance starts up, it registers itself with one of the Eureka servers.
Each microservice instance sends a heartbeat message to the Eureka server on a regular basis. It is telling the Eureka server that the microservice instance is okay and is ready to receive requests.
A client microservice uses a client library that regularly asks the Eureka service for information about available services.
When the client needs to send a request to another microservice, it already has a list of available instances in its client library and can pick (in a round-robin fashion) one of them without asking the discovery server.
Spring Cloud + Service discovery
Spring Cloud includes an abstraction of how to communicate with a discovery service such as "Netflix Eureka" and provides an interface called "DiscoveryClient". This interface can be used to interact with a discovery service to get information regarding available microservice instances.
Spring Boot can detect implementations (Apache ZooKeeper, Netflix Eureka, HashiCorp Consul, etc.) of the "DiscoveryClient" interface automatically during startup, we only need to add a dependency on the corresponding implementation to the class path.
In the case of Netflix Eureka, the dependency that's used by client microservices is "spring-cloud-starter-netflix-eureka-client".
Implementation
Let's create two microservices "order-service" and "product-service", the "order-service" calls a REST API exposed by "product-service".
Our goal is to implement service discovery to keep track of available microservice (product-service) instances.
Setting up a Netflix Eureka server
In order to set up a Netflix Eureka server using Spring Cloud, we need to take the following steps:
1) Create a Spring Boot project
Let's create a project with Spring Initializr, make sure to add required dependencies as shown in the picture below:
2) Enable EurekaServer
Add the @EnableEurekaServer annotation to the application class.
4) Configuration
We should switch off the client side behavior by telling it not to register with itself because our application should be acting as a server.
The server has a home page with a UI, let's point our browser to http://localhost:8761 to view the Eureka dashboard:
At the moment, we can see basic indicators, such as status and health indicators.
Connecting to a Netflix Eureka server
In this section, we will see how microservice instances register themselves with the Eureka server during their startup and how clients can use the Eureka server to find the microservice instances they want to call.
Register a microservice instance on the Eureka server
The "order-service" calls a REST API exposed by the "product-service", which means whenever a new instance of the "product-service" starts up, it should register itself with the "Eureka server".
1) The "product-service"
1.1) Create a spring boot project
For a Spring Boot Application to be discovery-aware, we have to include a "spring-cloud-starter-netflix-eureka-client" dependency into our classpath.
1.2) Configuration
We need to annotate a @Configuration with either @EnableDiscoveryClient or @EnableEurekaClient. Note that this annotation is optional if we have the spring-cloud-starter-netflix-eureka-client dependency on the classpath.
The @EnableEurekaClient tells Spring Boot to use Spring Netflix Eureka for service discovery explicitly.
1.3) Run
Let's start a few instance of the "product-service" on different ports:
java -jar product-service-0.0.1-SNAPSHOT.jar --server.port=8082 & java -jar product-service-0.0.1-SNAPSHOT.jar --server.port=8083 & java -jar product-service-0.0.1-SNAPSHOT.jar --server.port=8084 &
Now let's point our browser to http://localhost:8761 again to see "product-service" registration status on the Eureka Dashboard.
Use the Eureka server to find the microservice instances
The "order-service" calls a REST API exposed by the "product-service", which means whenever the "order-service" wants to call an API of the "product-service" it should have updated information about the "product-service" instances from the Eureka server.
1) The "order-service"
1.1) Create a spring boot project
For a Spring Boot Application to be discovery-aware, we have to include a "spring-cloud-starter-netflix-eureka-client" dependency into our classpath.
To use Swagger UI, we need to add an additional Maven dependency:
<dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-ui</artifactId> <version>1.6.14</version> </dependency>
1.2) Configuration
We need to annotate a @Configuration with either @EnableDiscoveryClient or @EnableEurekaClient. Note that this annotation is optional if we have the spring-cloud-starter-netflix-eureka-client dependency on the classpath.
The @EnableEurekaClient tells Spring Boot to use Spring Netflix Eureka for service discovery explicitly.
1.3) Add @LoadBalanced
Add a Spring bean in the configuration class, WebClientConf, that creates a load balancer-aware RestTemplate:
1.4) Test
Let's start a new instance of the "order-service" and test the overall flow through swagger: http://localhost:8080/swagger-ui.html
java -jar order-service-0.0.1-SNAPSHOT.jar --server.port=8080 &
Source code: GitHub