top of page

Blogs

Spring boot 3 microservices with Spring Cloud Part-1

Introduction

In this article, we will do a deep dive in to spring boot microservice development using Java, Maven and related spring components. You can find the code changes for the example



Spring boot 3 starter

You can use pre initialized project for creating each spring boot project. Follow below steps for the same

  1. Open https://start.spring.io. and add all the dependencies for an application.

  2. Select Maven and select Java version 17.

  3. Click Dependencies add required dependencies for a project.

  4. Click Generate.

  5. Download the resulting ZIP file, zip file contains project with all required libraries which you can import from IDE.


Implementing Service Discovery

Consider a case when there are number of small services running in your application and each service is communicating with number of other services. These services are distributed across the network and they have multiple instances running in the cloud environment. Each service instance undergo regular changes like ip address change, n/w upgrade and scaling. In this scenario, we need a service which can dynamically keep track of all changes and provide monitoring of each service.

Service discovery address this issue in detail. Service discovery is one of the microservice architecture pattern where each service is supposed to register itself to the registry server with meta data information like service name, host and port number. Service registry act as a central place to look up for any service and use the same. Individual services sends heartbeat to discovery server and let it know that the service is alive.

Service registry knows network location and status of all the services registered with server. If any service wants to call another service it just need to make a request to discovery server, rest all task related to searching, locating and connecting to the service is taken care by the eureka server. For example if department service wants to know all the employees for a particular department, it just need to create REST client and registry will provide that information. As employee service is already registered in the service registry, it has latest updates on location of the service and can give you the expected results.


In this example, we have used netflix eureka server. Perform below steps to create eureka server as a separate spring boot project.

  1. create a spring boot project with https://start.spring.io/

  2. Make sure to annotate application class with @EnableEurekaServer.

  3. Add server port and application name to application.yaml file

  4. Add following dependencies for eureka server project pom.xml file.


By default, registry also try to register itself, in order to avoid that you need to make eureka.client.register-with-eureka=false


server:
  port: 8761
spring:
  application:
    name: service-registry
eureka: 
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      default-zone: 		   http://${eureka.instance.hostname}:${server.port}/eureka

<dependencies>
	<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>

	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>
</dependencies>

Spring cloud config server

spring cloud config server provides central place for all configuration present in your application. In a microservice environment it is not possible to manage separate configuration for each service therefore a separate microservice for configuration is considered called config server. There is a need to manage all microservice configuration in a consistent way and can handle configurations for 100s of microservices for different environments. cloud config servers comes up with number of benefits including integration with version control system. It can pull the files directly from the version control instead of separately modifying microservice code and deploying again and again. In a nutshell config server provides managed way of handling config changes without requiring separate microservice instance restart for each small config change.


consider below maven dependencies for spring config server project.

<dependency>

    <groupId>org.springframework.cloud</groupId>

    <artifactId>spring-cloud-starter-config</artifactId>

</dependency>

<dependency>

<groupId>io.micrometer</groupId>

<artifactId>micrometer-tracing-bridge-brave</artifactId>

</dependency>

     <dependency>

        <groupId>io.zipkin.reporter2</groupId>

       <artifactId>zipkin-reporter-brave</artifactId>

</dependency>

config server creation steps:


  1. Create a new @SpringBootApplication class and annotate it with @EnableConfigServer to enable the configuration server functionality.

  2. create a config directory to keep each microservice yaml configuration file

  3. create a application.yaml file and add server port and active profile

  4. Start the configuration server, and it will automatically serve the configuration files to the microservices in our application.


Log tracing with Zipkin server

zipkin is a distributed tracing system allows you to track API requests, response, queries, logs and other meta data about the operations. zipkin also provides UI to view traces. when there are number of microservices inter communicating with each other it is important to capture the log trace. spring boot integration collects all the log data within microservice and publish it to the zipkin server where you can find the entire trace from start till end. you can find more details here. https://zipkin.io/

you can easily download, install and run the zipkin server locally and it will look like

java -jar zipkin.jar
running zipkin server locally from commandline
zipkin server

you need to add the following dependencies to the config server project to add zipkin support. Also yaml configuration needs to be updated for employee and department microservices.

<dependency>
		      <groupId>io.micrometer</groupId>
		      <artifactId>micrometer-tracing-bridge-brave</artifactId>
	    </dependency>
    	<dependency>
     	 	<groupId>io.zipkin.reporter2</groupId>
      		<artifactId>zipkin-reporter-brave</artifactId>
    	</dependency>

Spring boot 3 Microservice with Spring Cloud

Now, let's develop some microservices that will interact with each other using RESTful APIs. For simplicity, let's consider two microservices: employee-service and department-service.

  1. create a new spring boot application for each microservice as explained before.

  2. add the @EnableDiscoveryClient annotation to enable service discovery using Spring Cloud Netflix Eureka. Each microservice should be a discovery client since it needs to register with eureka server.

  3. use Spring Web to expose RESTful endpoints and handle the necessary business logic in each microservice

  4. add config server url to the microservice project so as to look out for all config parameters

  5. add employee-service.yaml and department-service.yaml to config server


below dependencies should be added to both employee and department project pom.xml file. Additional dependencies for zipkin server and junit can be added

<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</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>org.springframework.cloud</groupId>
	      <artifactId>spring-cloud-starter-config</artifactId>
	    </dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

department-service.yaml as below

server:
  port: 8081
    
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      default-zone : http://localhost:8761/eureka/
      
spring.zipkin.base-url : http://localhost:9411/
management:
  tracing:
    sampling:
     probability : 1.0

eureka.instance.hostname: localhost
eureka.instance.prefer-ip-address: true

We are going to add rest end points to employee and department services and it will require us to create basic spring mvc skeleton including controllers ,services and repositories. In this example we are not adding any external database and we will keep it for illustration purpose.


employee-service APIs

/employee/add

/employee/{id}

/employee/all

find all employees belongs to a department

/employee/department/{departmentId}


department-service APIs

/employee/add

/employee/{id}

/employee/all

find all departments with employees /employee/all/department-employee


Web Client

if we want to get all employees for a department, we need to use employee microservice from department service. we have to create employee client and connect from department service.

We have below options to create a client using spring boot.

  1. RestTemplate(deprecated)

  2. Feign client

  3. Webclient

  4. Declarative HttpClient

FeignClient is synchronous and follows Thread per request architecture style. Spring webclient is a non blocking reactive library to create REST client included from Spring 5 where as Webclient provides fluent API for binding and executing http request.


We are going to use the Declarative http interface which is introduced in spring 6 and spring boot 3. It supports both blocking and reactive return values. Following dependency needs to be added to department service project

<dependency>
      		<groupId>org.springframework.boot</groupId>
	        <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

Create the EmployeeClient interface and annotate it with @HttpExchange. The annotation represents that we can include method on an HTTP service interface as an HTTP endpoint. Now add the method to collect all employees for a department.

findByDepartmentId(@PathVariable("departmentId") Long departmentId)


@GetExchange - denotes that it is a HTTP Get method call


Let us summarize what we have achieved till this point. we have learned importance of service discovery microservice pattern and created the eureka server project. We also understood the concept of spring cloud config server and its usage then we added the zipkin server into the stack.

Lastly, couple of microservices with REST end points along with declarative http client to fetch the employee data. We should be good to build the project using maven and start the individual microservice.

Here we can use IDE provided maven or we can include local maven installation as well. If you want to include external maven just go to your eclipse Window->Preference->Maven->Installations and provide local maven installation path.

Once you have all services up and running, you can verify the logs in the console. The spring boot dashboard should look like below :


Spring boot dashboard in STS
Spring boot dashboard

you can notice that when service registry is up it shows both employee and department service status in the browser.



Spring eureka server end point
Spring eureka server

API Testing

we use the postman to perform API testing. you can check employee and department service APIs by providing respective data.


Add deparment end point
postman client



add employee end point
postman client

get all employees


get all employees end point
postman client

get all departments


get all department end point
postman client

Also notice that these API requests can be tracked in the zipkin server as below.


zipkin server UI showing HTTP requests history for department service
zipkin UI

You can find the code changes for the example here


Conclusion

Here, we have explored the step-by-step process of developing a microservices application using Spring Cloud. We have covered essential components like the configuration server, microservices, discovery service, http client, and API Testing. We will see some more features like Spring cloud gateway, JUnit 5, Code coverage with Jacoco and Sonarqube integration in the part-2


Recent Posts

See All

Comments


© 2023 DevHabit - All Rights Reserved

  • Instagram
  • GitHub
  • Facebook
  • Twitter
bottom of page