1. Introduction
In this tutorial we’ll discuss how to implement client side service discovery. Spring Cloud project makes Service Discovery setup is very easy with the help of following components:
- Spring Cloud Netflix Eureka is a service discovery solution based on Netflix’s Eureka, designed for microservices architecture. It enables automatic registration and discovery of services, facilitating seamless communication between microservices.
- Spring Cloud Load Balancer is a lightweight, client-side load-balancing solution provided by the Spring Cloud ecosystem. It replaces Netflix Ribbon as the default load-balancer in Spring Cloud and is fully integrated with Spring Boot and Spring Cloud.
- Netflix Feign is a declarative HTTP client for microservices communication. It simplifies service-to-service calls by abstracting the complexity of HTTP requests, allowing developers to define web service clients using interfaces and annotations.
2. Setup Eureka server
Following is the main dependency we need to add for eureka server.
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
Here is the complete pom.xml
:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.4.0</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.learnitweb</groupId> <artifactId>eurekaserver</artifactId> <version>0.0.1-SNAPSHOT</version> <name>eurekaserver</name> <description>Service discovery project </description> <url/> <licenses> <license/> </licenses> <developers> <developer/> </developers> <scm> <connection/> <developerConnection/> <tag/> <url/> </scm> <properties> <java.version>17</java.version> <spring-cloud.version>2024.0.0-RC1</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> </project>
Add @EnableEurekaServer
annotation to the main application class.
package com.learnitweb.eurekaserver; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication @EnableEurekaServer public class EurekaserverApplication { public static void main(String[] args) { SpringApplication.run(EurekaserverApplication.class, args); } }
Once you start the service, you can access the http://localhost:8070
. The page looks similar to the following image:
3. Registering a service with the Eureka server
Let’s create a service and register with the Eureka server. We’ll name our service as Product service. Following is the main dependency we need to add to the pom.xml
.
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
Following is the pom.xml
.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.4.0</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.learnitweb</groupId> <artifactId>productservice</artifactId> <version>0.0.1-SNAPSHOT</version> <name>productservice</name> <description>Project for Product microservice</description> <url/> <licenses> <license/> </licenses> <developers> <developer/> </developers> <scm> <connection/> <developerConnection/> <tag/> <url/> </scm> <properties> <java.version>17</java.version> <spring-cloud.version>2024.0.0-RC1</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> </project>
Next, we need to configure product details service to connect to the Eureka server:
eureka: client: fetchRegistry: true registerWithEureka: true service-url: defaultZone: http://localhost:8070/eureka/ instance: hostname: localhost prefer-ip-address: true
Here is the complete application.yml
file:
server: port: 8071 spring: application: name: ProductService eureka: client: fetchRegistry: true registerWithEureka: true service-url: defaultZone: http://localhost:8070/eureka/ instance: hostname: localhost prefer-ip-address: true info: app: name: ProductService description: A sample Spring Boot application for product service. version: 1.0.0 company: name: Learnitweb.com website: https://learnitweb.com address: Some sample address management: endpoints: web: exposure: include: info, health endpoint: info: enabled: true info: env: enabled: true
As soon as you start the product service microservice, it is registered with Eureka server. The dashboard of the Eureka server should look like the following:
You can click on the link under the ‘Status’ column and get the service information.
4. See all registered apps
The endpoint http://localhost:8070/eureka/apps
provides a list of all registered applications (services) in the Eureka Server’s registry. It returns information about the microservices currently registered, such as:
- Application names.
- Instance IDs.
- Instance statuses (UP, DOWN, etc.).
- Metadata like IP address, port, and health check URL.
5. De-registration from Eureka server when microservices shutdown
To gracefully de-register from Eureka server, use the /actuator/shutdown
.
The /actuator/shutdown
endpoint in Spring Boot Actuator allows graceful shutdown of a running application by triggering the ApplicationContext
to close. This is particularly useful in microservice architectures where services might need to be shut down programmatically or remotely.
6. Conclusion
In this tutorial, we walked through the process of setting up service discovery using a Eureka server, a critical component of microservices architecture. By implementing Eureka, you enable your microservices to dynamically register and discover each other, ensuring scalability, fault tolerance, and seamless communication across the ecosystem.
In the next tutorial, we’ll see how this works and other concepts of service discovery.