Complete microservices architecture with real examples — Step 3 — Service registry
Welcome to today’s new tech topic. Today, we are going to describe another important component in the microservices architecture, the Service Registry. Both advantageous and disadvantageous are there with the service registry. The main benefit of that is to keep all address details of microservices globally and the ability to ignore each individual hostnames and port details when a service is being called by the end-user or another service. Just we can call services of a microservice only with its name. On the other hand, there is a drawback because we have to add a mandatory configuration in all microservices which are going to be registered with the registry. Anyway, we will quickly look into the practical example of this vastly used component in the microservices architecture. This is an extension of the previous two posts, one was for Department Service and the other for User Service.
Step 3 — Service Registry
Can you guess how we can implement a service registry in the microservices architecture? Again we have to set up another microservice with different dependencies. This is the time to dive into the codebase. Here we go.
Initialization details
- Project build tool: Maven
- Language: Java
- Spring boot: 2.4.2
- Project Metadata
Group: com.agnasarp
Artifact: agnasarp-service-registry
Name: agnasarp-service-registry
Description: Agnasarp Service Registry
Package name: com.agnasarp.serviceregistry
Packaging: Jar
Java version: 8
- Dependencies:
Eureka Server: spring-cloud-netflix Eureka Server.
Then, we will import the project into IntelliJ Idea.
Project structure
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
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>2.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.agnasarp</groupId>
<artifactId>agnasarp-service-registry</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>agnasarp-service-registry</name>
<description>Agnasarp Service Registry</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2020.0.1</spring-cloud.version>
</properties>
<dependencies>
<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>
</project>
application.yml
server:
port: 8761
eureka:
client:
register-with-eureka: false
fetch-registry: false
AgnasarpServiceRegistryApplication.java
package com.agnasarp.serviceregistry;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class AgnasarpServiceRegistryApplication {
public static void main(String[] args) {
SpringApplication.run(AgnasarpServiceRegistryApplication.class, args);
}
}
Now, we have to set Department Service and User Service as discovery clients and for that, we need to add one dependency in the pom.xml file and put an annotation in the main class. Ultimately we have to register these services in the registry by adding few configurations in the application.yml file.
Department Service
To work with Service Registry, other microservices like Department Service and User Service need some modifications as below.
pom.xml
Need to add highlighted dependency to the pom.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
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>2.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.agnasarp</groupId>
<artifactId>agnasarp-department-microservice</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>agnasarp-department-microservice</name>
<description>Agnasarp Department Microservice</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2020.0.1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<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>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</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>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.yml
Need to add highlighted configurations to the application.yml file
server:
port: 8280
spring:
application:
name: DEPARTMENT-SERVICE
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
hostname: localhost
AgnasarpDepartmentMicroserviceApplication.java
Need to add highlighted annotation to AgnasarpDepartmentMicroserviceApplication.java file.
package com.agnasarp.department;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class AgnasarpDepartmentMicroserviceApplication {
public static void main(String[] args) {
SpringApplication.run(AgnasarpDepartmentMicroserviceApplication.class, args);
}
}
All other source code should remain the same and we have to apply the same above changes to the User Service as well.
User Service
pom.xml
Need to add highlighted dependency to the pom.xml file.
<?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>2.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.agnasarp</groupId>
<artifactId>agnasarp-user-microservice</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>agnasarp-user-microservice</name>
<description>Agnasarp User Microservice</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2020.0.1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<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>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</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>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.yml
Need to add highlighted configurations to the application.yml file
server:
port: 8380
spring:
application:
name: USER-SERVICE
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
hostname: localhost
AgnasarpUserMicroserviceApplication.java
Need to add highlighted annotation to AgnasarpUserMicroserviceApplication.java file. Here we have to explicitly tell RestTemplate to loadbalance if there are multiple instances of Department Service.
package com.agnasarp.user;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableEurekaClient
public class AgnasarpUserMicroserviceApplication {
public static void main(String[] args) {
SpringApplication.run(AgnasarpUserMicroserviceApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
UserService.java
Need to replace IP and Port details in UserService.java file by application name as highlighted.
package com.agnasarp.user.service;
import com.agnasarp.user.entity.User;
import com.agnasarp.user.repository.UserRepository;
import com.agnasarp.user.vo.Department;
import com.agnasarp.user.vo.ResponseTemplateVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class UserService {
private static final Logger log = LoggerFactory.getLogger(UserService.class);
@Autowired
private UserRepository userRepository;
@Autowired
private RestTemplate restTemplate;
public User saveUser(User user) {
log.info("Inside saveUser method of UserService");
return userRepository.save(user);
}
public ResponseTemplateVo getUserWithDepartment(Long userId) {
log.info("Inside getUserWithDepartment method of UserService");
ResponseTemplateVo responseTemplateVo = new ResponseTemplateVo();
User user = userRepository.getUserByUserId(userId);
Department department = restTemplate.getForObject("http://DEPARTMENT-SERVICE/" +
"departments/" + userId, Department.class);
responseTemplateVo.setUser(user);
responseTemplateVo.setDepartment(department);
return responseTemplateVo;
}
}
If we configure all well, we can see the Service Registry is up and running by using port 8761 on localhost as below. All two microservices are working fine with Service Registry as well.
Eureka Server Dashboard
That is all for today’s post. Hope you have a good understanding of microservices and service registry concepts. If you need the source code of these services, please click the below buttons to get them from GitHub. We will meet again with this kind of tech topic soon. Until then bye bye!
Download source from github:
https://github.com/Agnasarp/agnasarp-service-registry
https://github.com/Agnasarp/agnasarp-department-microservice
https://github.com/Agnasarp/agnasarp-user-microservice
Go to Step 1 — Department Microservice
Go to Step 2 — User Microservice
Originally published at https://www.agnasarp.com on March 8, 2021.