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

Index
How to Implement PostgreSQL Full-Text Search with Spring Boot

15 min

Spring's transaction management with the @Transactional annotation

9 min

Spring Boot Rest APIs with PostgreSQL (Spring Boot + Rest APIs)

15 min

Caching in Spring Boot (@Cacheable, @CacheEvict & @CachePut)

21 min

Declarative REST Client in Spring Boot (Spring 6 HTTP Interface)

13 min

Circuit Breaker in Spring Boot (Spring Cloud Circuit Breaker + Resilience4j)

12 min

Handling Concurrent Service Calls in a Spring Boot Application: Asynchronous vs. Reactive Approaches

11 min

Profiling a Spring Boot application with Pyroscope

7 min

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

9 min

Dockerize Spring Boot app and Push image to DockerHub (Spring Boot + DockerHub)

4 min

Creating a Jenkins Pipeline for Spring Boot application

2 min

Monitoring Microservices (Spring Boot + Micrometer + Prometheus + Grafana)

7 min

Edge Server Pattern in Microservices (Spring Cloud Gateway)

7 min

Circuit Breaker Pattern in Microservices (Spring BOOT + Resilience4j)

4 min

Spring Cloud config server setup with Git

8 min

Distributed Tracing in Microservices (Spring Cloud Sleuth + Zipkin)

9 min

Circuit Breaker Pattern with Resilience4J in a Spring Boot Application

24 min

Deploying Spring Boot microservices on Kubernetes Cluster

12 min

Reactive programming in Java with Project Reactor

50 min

Spring Reactive with PostgreSQL (Spring Boot WebFlux + PostgreSQL)

13 min

Spring Reactive, Thymeleaf Hello World (Spring Webflux + Thymeleaf + JS/CSS)

9 min

Problem JSON (application/problem+json) in Spring WebFlux

15 min

Spring Boot Login/Logout (Spring Security + MySql + Thymeleaf)

21 min

Securing Server-to-Server Communication with "Spring Boot" & "OAuth 2"

18 min

Integrating Elasticsearch with a Spring Boot and PostgreSQL application

16 min

Sending Emails in Spring Boot via SMTP

7 min

How to create a basic Spring 6 project using Maven

5 min

Spring Boot, Thymeleaf Hello World (Spring Boot + Thymeleaf + JS/CSS)

9 min