1. Introduction
Microservice architecture or simply Microservices has gained a lot of traction in recent times. They are best for agile methodology and ensure better continuous delivery. Big organizations like eBay, Amazon, and Netflix are embracing it.
Traditional monolithic applications operate as a single unit. A minor change in the application needs an entire application to deployed. There is no option to scale up/down certain modules in the application independently, the entire application needs to scale up/down.
In Microservice, an application is deployed as a suite of smaller and independent applications each one managing a separate business operation/entity. These services can be independently develop (even in different languages), scaled up/down, and deployed. They typically communicate with each other using REST API.
However, there are also downsides to this approach:
- Management/Monitoring of distributed services becomes painful as their number grows.
- Debugging a bug that spans multiple services is difficult.
- Each service maintains its configuration (typically in a properties/yml file). It’s also common that certain config parameters are use in multiple services. When a config parameter has to change, we need to track all the services using it, change the value in all of them and build and deploy each dedicated Java Developers.
Spring Cloud Config attempts to resolve the configuration drawback mentioned in #3.
2. Spring Cloud Config
Spring Cloud Config employs a Server-Client approach for storing the configuration externally in 1 place. Any configuration changes don’t need to deploy the associated services, in-fact these changes are reflected automatically.
2.1 HLD and Execution Flow
2.2 Spring Cloud Config Components
Spring cloud Config consists of following components:
2.2.1 Git Repository
The file containing configuration (typically .properties or .yml) is hosted in a git repository. The default implementation of the Spring cloud config storage uses the GIT repository.
This repository maintains properties for each environment (dev, local, prod) separately using profile-specific config files such as application. Properties, application-local.properties, application-dev.properties.
2.2.2 Config Server
This is a standalone application wherein the path to the git repository is configured. It also provides REST API endpoints to read the configuration in the underlying git repository.
2.2.3 Config Clients
These are the individual Microservice, which bind to Spring Cloud Config Server. All property changes in git repo are reflected without redeploying the Microservice. Spring beans in this should be annotated with @RefreshScope, so that Whenever any parameter in the configuration file hosted in git changes, on triggering /refresh endpoint, the application context is reloaded with new config without application restart.
3. Project
In this project, we will create a 2 projects
- Git backed config server
- Config client microservice which binds to Config server. All configuration changes will be reflected without redeploying them.
3.1 Git Repository
Before starting with projects, let’s first create a git repository that will host the central configuration.
1. Go to a folder and create an empty git repository in it.
2. Create properties file in it.
Here I have create 2 files
application-dev.properties- which will be used when the active profile for client = dev
application-local.properties- which will be used when the active profile for client = local
The contents of application-local.properties is
3. Add the files to staging area and commit the changes
3.2 Config Server Project
This is a simple spring boot project with following structure
3.2.1 Maven Dependencies
Here we are using latest version of spring-boot-starter as well as Spring Cloud Finchley Release Train.
3.2.2 Main Application Class:
We have added the EnableConfigServer annotation before the class so that project will act like a spring config server
3.2.2 Application properties
Here we have chosen server port as 8888. spring.cloud.config.server.git.uri will bind the git repository. Here we are using local git repo but we can also use the remote repository by changing to its URL.
3.2.4 Start the config server
1. Go to the project’s root and issue >>> mvncleaninstall 2. If build is success, launch the jar generated in the target folder >>> java-jartarget/cloud-config-server-0.0.1-SNAPSHOT.jar 3. We can use REST Endpoints of the Config server for retrieving the configuration >>> /{applicationName}/{profile}
Here the setup of config server is complete.
3.3 Config Client Application
Startbuilt the latest Spring Boot application that uses the Config Server to load its own configuration and that refreshes its configuration to reflect modifies in configuration on-demand continue started.
It is a spring-boot application, with following structure:
3.3.1 Maven dependencies
Here we are using the latest version of spring-boot-starter as well as Spring Cloud Finchley Release Train.
Explanation :
1. Spring-boot-starter-web - for enabling MVC
2. Spring-cloud-starter-config - This dependency is used to connect to Config Server.
3. Spring-boot-starter-actuator – This dependency exposes the operational endpoints of the application. We’ll need /refresh the endpoint to refresh the application context when changes are made to the git repository.
3.3.2 Main Application Class :
3.3.3 Stateful Beans
In order to demonstrate the spring cloud configuration more clearly, we are creating a stateful spring bean here.
The configuration class to create its bean is :
Here the bean is annotated with @RefreshScope, so that bean will be re-initialized at run-time.
3.3.4 Controller
We are also exposing the REST endpoints, so demonstrate how beans and properties are changed.
3.3.5 Application Properties
Here application.properties don’t have any specific configuration parameters, this is because it gets its properties from the config-server.
The significance of a handful of properties configured here is:
- spring.application.name - name of the application
- server.port - the application port
- spring.cloud.config.uri - the URL of config server, we created above
- management.endpoints.web.exposure.include - We had added spring-boot-starter-actuator in our pom, which exposes operational endpoints of our application. They include /health, /info, /metrics, /refresh. Of these we only want /refresh endpoint to refresh the application context, when changes are made to git repository.
3.3.6 Starting the config-client :
1. Go to the project’s root and issue >>>mvncleaninstall 2. If build is success, launch the jar generated in the target folder >>>java-jar-Dspring.profiles.active=localtarget/config-client-0.0.1-SNAPSHOT.jar Here we have selected the active profile as “local”, so that it will read properties from “application-local.properties” from git repo. Changing the same to “dev”, means it will read properties from application-dev.properties from git repo.
4. Demonstration
To demonstrate the application :
1. Let’s first hit the client-config endpoint, to get the latest client data
2. Make changes in Git Repo
We have made changes to application-local.properties, so that it looks like
Commit the changes
3. Confirm if the properties are changed in client:
You can find, that old properties are still reflected inspite of changing the file in git repository and committing the changes. This is where the /refresh endpoint of actuator comes in.
4. Trigger Refresh Endpoint on Client:
We can use CURL to trigger the same or any other REST client.
The response is list of configuration properties which are changed.
5. Now Again hit client endpoint
Thus here we can see
1. The properties were refreshed.
2. The beans with @RefreshScope was also reinitiated.
Dynamic configuration management in microservice architecture with Spring CloudBy @bartekslota Video: https://t.co/WwnmY7DWMeSlides: https://t.co/R1m0JXNy5SGitHub repos: https://t.co/M083YRlCPfhttps://t.co/VOZUZzt3XF#springio18 #replay @springcloud
— Spring I/O (@spring_io) July 13, 2018
Conclusion
Thus we have accomplished:
- Centralized configuration of our services in spring. This configuration is hosted in a git repository.
- Created Cloud Config Server which secures the get store
- Created Cloud Client services to devour the configuration on startup and then refresh the configuration without restarting.
- Depending on the client application’s active profile, changes are only reflect from the corresponding file.