Complete microservices architecture with real examples — Step 3 — Service registry

Agnasarp
6 min readMar 8, 2021

--

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.

Service Registry

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

Spring Initialzr — Service Registry
  • 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

Project structure of service registry in IntelliJ Idea

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

http://localhost:8761/

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.

--

--

Agnasarp

Agnasarp is a technology-focused blog that has enough information about cutting-edge technologies that you can use for your problems. Stay with us!