Eureka Service Registry
0 CommentsDistributed Microservices Systems typically comprise a large number of smaller services. These services communicate with each other to perform operations. In order to communicate, one service needs the address of the other service to call. However, service addresses are dynamic in modern microservices systems. For example, if a service is running on one IP and listening to a specific port gets unhealthy, another service will automatically spin up at a different IP listening on a different port to take its place. But the challenge is – if the caller service is hardcoded with the address of the previous service that failed, how it will reach the new one? This is addressed by the Microservices Service Discovery pattern. One of the most popular implementations of this pattern is Eureka Service Registry.
With Eureka running in your microservices system, services (Eureka Clients) will register with the Eureka server with its name during start-up. Subsequently, these services (Eureka Clients) will keep sending heartbeats to Eureka.
Now assume a service, say Service A (calling service) wants to communicate with another service, Service B. With Eureka running, Service A can perform a look-up for Service B in Eureka. Once discovered, Service A can can communicate with the Service B with the service name.
The following Figure illustrates this.
In this post, you’ll learn how to create a service (Eureka Client) that registers with Eureka for discovery.
Eureka Service Discovery Example
In this example, we will use the Netflix Eureka server as the service registry server. Next, we will create a service that acts as a Eureka client. Finally, we will make the client to register with Eureka.
Let’s start by creating a Spring Boot multi-module project for this post.
The multi-module project contains two Spring Boot services: Eureka Service and Employee Service.
This is how the application looks in the Projects window of IntelliJ.
You can find the project structure in the accompanied source code of this post on Github.
Setting up the Eureka Server
In Spring Boot microservices, you implement Eureka server as an independent Spring Boot service.
Maven Dependency
The Eureka server requires the spring-boot-starter-web
, spring-cloud-starter-netflix-eureka-server
dependencies to be added in pom.xml
file.
pom.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
Eureka Server Main Class
The next step is to refactor the main class to configure it as a Eureka server, like this.
@EnableEurekaServer @SpringBootApplication public class SpringEurekaServerApplication { public static void main(String[] args) { SpringApplication.run(SpringEurekaServerApplication.class, args); } }
The preceding code adds the @EnableEurekaServer
annotation on the class. This annotation is used to mark this Spring Boot application as a Eureka server.
We will now add some configuration settings in application.properties
.
The application.properties File
server.port=8761 eureka.client.register-with-eureka=false eureka.client.fetch-registry=false
The preceding code sets the server.port
property to set 8761
as the port number.
It also sets the value for eureka.client.register-with-eureka
to false
. This prevents the Eureka server from registering itself on start-up.
When a Eureka server starts up, by default it searches for other peer registries. In order to prevent this, the code sets the eureka.client.fetch-registry
property to false
.
Testing the Eureka Server
Run the Spring Boot Application and open browser at http://localhost:8761/
This is the Eureka Server Dashboard.
At this point there are no service registration with Eureka. As a result, the dashboard displays the “No instances available” message.
Setting up the Eureka Client
For this example, I am taking a Spring Boot RESTful service employee-service
and shall configure it as a Eureka client.
Maven Dependency
The Eureka Client requires spring-boot-starter-web
, and spring-cloud-starter-netflix-eureka-client
dependencies in pom.xml
file.
pom.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
Next, let us refactor the Main class of the Eureka Client.
Eureka Client Main Class
The main class of employee-service
, which is our Eureka client is this.
package guru.springframework.controller; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @EnableEurekaClient @SpringBootApplication public class EmployeeApplication { public static void main(String[] args) { SpringApplication.run(EmployeeApplication.class, args); } }
The preceding code annotates the main class with @EnableEurekaClient
. This annotation instructs Spring Boot to scan the classpath and identify that this service is a Eureka client.
You will also need to configure the settings in application.properties
and bootstrap.properties
file.
The bootstrap.properties File
spring.application.name = employee-service
In the bootstrap.properties
file, we will specify the name of the service. Other service can use this name for communication.
Note:
bootstrap.properties
file is picked up before the application.properties
file by Spring Boot.
Spring uses the spring.application.name
property in the earliest phases of service configuration. Therefore, by convention, this property resides in the bootstrap.properties
file.
The other configuration settings are done in the application.properties
file.
The application.properties File
eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka eureka.client.register-with-eureka= true
In the preceding code, the eureka.client.serviceUrl.defaultZone
property indicates the address of the Eureka server.
Client service, which in our case is employee-service
will use this URL to register with the Eureka server. In this particular instance, the URL is set to http://localhost:8761/eureka
.
The other property value is set to true.
This indicates that this service should register itself with the Eureka server
The Controller
For the purpose of demonstration, let us add a REST controller to the employee-service
. The controller code is this.
package guru.springframework.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("api/v1") public class EmployeeController { @RequestMapping("/greet") public String greetWelcomeMessage(){ return "Welcome to all the employees !"; } }
Run the Eureka Client Application and open the Eureka Dashboard at at http://localhost:8761/
You can see one entry for employee-service
in the dashboard. This indicates that both Eureka server and Client are aware of each other.
Summary
Service Discovery with a standalone Eureka server is a common use case. However, the Eureka server in this scenario becomes a Single Point of Failure. If the Eureka server is down, parts of your system or at times, the entire system can go down. In order to mitigate this and make your system fault tolerant, you can deploy Eureka as a cluster of servers. Individual servers of this cluster are called peers. The peers during start up, register and synchronize their registration with each other.
You can find the source code of this post here on Github.
For in-depth knowledge on using Eureka with in Spring Boot microservices, you can check my Udemy Best Selling Course Spring Boot Microservices with Spring Cloud Beginner to Guru