Skip to main content

Service discovery in Spring Boot (Spring Cloud + Netflix Eureka)

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

Comments

Popular posts from this blog

Deploying Spring Boot microservices on Kubernetes Cluster

This article guides you through the deployment of two Spring Boot microservices, namely "order-service" and "inventory-service," on Kubernetes using "MiniKube" . We will establish communication between them, with "order-service" making calls to an endpoint in "inventory-service." Additionally, we will configure "order-service" to be accessible from the local machine's browser . 1) Create Spring Boot microservices The Spring Boot microservices, "order-service" and "inventory-service," have been developed and can be found in this GitHub repository. If you are interested in learning more about creating Spring Boot REST microservices, please refer to this or this (Reactive) link. 2) Build Docker Images The Docker images for both "order-service" and "inventory-service" have already been generated and deployed on DockerHub, as shown below. codeburps/order-service cod...

Circuit Breaker Pattern with Resilience4J in a Spring Boot Application

Read Also: Spring Cloud Circuit Breaker + Resilience4j Resilience4j is a lightweight fault tolerance library that draws inspiration from Netflix Hystrix but is specifically crafted for functional programming. The library offers higher-order functions, known as decorators , designed to augment any functional interface, lambda expression, or method reference with features such as Circuit Breaker, Rate Limiter, Retry, or Bulkhead . These functionalities can be seamlessly integrated within a project, class, or even applied to a single method. It's possible to layer multiple decorators on any functional interface, lambda expression, or method reference, allowing for versatile and customizable fault tolerance. While numerous annotation-based implementations exist online, this article focuses solely on the reactive approach using router predicates and router functions . How Circuit Breaker Pattern works? In general, a circuit breaker functions as an automatic electrical s...

How to create a basic Spring 6 project using Maven

Below is a step-by-step guide to creating a basic Spring project using Maven. 1) Create a Maven Project Use the following Maven command to create a new Maven project. mvn archetype:generate -DgroupId=com.tb -DartifactId=spring-demo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false 2) Import in IntelliJ IDEA If you haven't already, open IntelliJ IDEA on your system. Go to "File" > "New" > "Project from Existing Sources..." . In the file dialog, navigate to the directory where your Maven project is located. Select the pom.xml file within the project directory and click "Open." 3) Update pom.xml In total, the application requires the below-mentioned dependencies: 4) Create Spring Configuration Create a Java configuration class that uses annotations to define your Spring beans and their dependencies. This class should be annotated with @Configuration . 5) Create the Main Application C...