spring

Dynamic Configuration Management in Microservice Architecture with Spring Cloud

This article is about the dynamic configuration management in Microservice Architecture with Spring Cloud.

1. Introduction

Dynamic configuration is the ability to change the behavior and functionality of a distributed system without bringing it down. It lets the developers modify the configuration at runtime. It also helps to test functionality in a production-like environment without affecting the live users. This feature can also be used effectively for the A/B testing of a system.

2. Spring Cloud

Spring Cloud provides tools for developers to quickly build some of the common patterns in distributed systems (e.g. configuration management, service discovery, circuit breakers, intelligent routing, micro-proxy, a control bus, one-time tokens, global locks, leadership election, distributed sessions, cluster state).

You can also check this tutorial in the following video:

Spring Cloud Tutorial – video

Coordination of distributed systems leads to boilerplate patterns, and using Spring Cloud developers can quickly stand up services and applications that implement those patterns. They will work well in any distributed environment, including the developer’s own laptop, bare metal data centers, and managed platforms such as Cloud Foundry.

2.1 Spring Cloud Config

Spring Cloud Config provides server and client-side support for externalized configuration in a distributed system. With the Config Server, you have a central place to manage external properties for applications across all environments. The concepts on both client and server map identically to the Spring Environment and PropertySource abstractions, so they fit very well with Spring applications but can be used with any application running in any language.

As an application moves through the deployment pipeline from dev to test and into production you can manage the configuration between those environments and be certain that applications have everything they need to run when they migrate. The default implementation of the server storage backend uses git so it easily supports labeled versions of configuration environments, as well as being accessible to a wide range of tooling for managing the content. It is easy to add alternative implementations and plug them in with the Spring configuration.

2.2 Features

Spring Cloud Config Server features:

  • HTTP, resource-based API for external configuration (name-value pairs, or equivalent YAML content)
  • Encrypt and decrypt property values (symmetric or asymmetric)
  • Embeddable easily in a Spring Boot application using @EnableConfigServer

Config Client features (for Spring applications):

  • Bind to the Config Server and initialize Spring Environment with remote property sources
  • Encrypt and decrypt property values (symmetric or asymmetric)

3. Spring Cloud Config Server

Spring Cloud Config Server provides an HTTP resource-based API for external configuration (name-value pairs or equivalent YAML content). The server is embeddable in a Spring Boot application, by using the @EnableConfigServer annotation.

LocalConfigServer.java

@SpringBootApplication
@EnableConfigServer
public class LocalConfigServer {
  public static void main(String[] args) {
    Application.run(LocalConfigServer.class, args);
  }
}

To start the spring cloud config server run mvn spring-boot:run inside the spring-cloud-config-server folder. The server is a Spring Boot application, so you can run it from your IDE if you prefer to do so (the main class is ConfigServerApplication). Spring Cloud Config Server pulls configuration for remote clients from various sources: git repository, JDBC compatible database, Subversion, Hashicorp Vault, Credhub and local filesystems.

4. Spring Cloud Config Client

To use the client features in an application, you can build it as a Spring Boot application that depends on spring-cloud-config-client. The most convenient way to add the dependency is with a Spring Boot starter org.springframework.cloud:spring-cloud-starter-config. There is also a parent pom and BOM (spring-cloud-starter-parent) for Maven users and a Spring IO version management properties file for Gradle and Spring CLI users.

Now you can create a standard Spring Boot application that will pick the external configuration from the default local config server. The default port for the server is 8888. To modify the startup behavior, you can change the location of the config server by using bootstrap.properties:

spring.cloud.config.uri: https://mylocalconfigserver.com

5. Dynamic Configuration with Spring Cloud Example

We will need a Config service to act as a sort of intermediary between our Spring application and a version-controlled repository of configuration files. We can use the Spring Cloud.s @EnableConfigServer to start a config server. This is a regular Spring Boot application with one annotation added to enable the config server.

The below class is from configuration-service/src/main/java/com/example/configurationservice/ConfigurationServiceApplication.java

ConfigurationServiceApplication.java

package com.example.configurationservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@EnableConfigServer
@SpringBootApplication
public class ConfigurationServiceApplication {

  public static void main(String[] args) {
    SpringApplication.run(ConfigurationServiceApplication.class, args);
  }
}

The Config Server needs to know which repository to manage. There are several choices here but start with a Git-based filesystem repository. You could as easily point the Config Server to a Github or GitLab repository. On the file system, create a new directory and run git init in it. Then add a file called a-bootiful-client.properties to the Git repository. Then run git commit in it. Later, you will connect to the Config Server with a Spring Boot application whose spring.application.name property identifies it as a-bootiful-client to the Config Server. This is how the Config Server knows which set of configuration to send to a specific client. It also sends all the values from any file named application.properties or application.yml in the Git repository. Property keys in more specifically named files (such as a-bootiful-client.properties) override those in application.properties or application.yml.

Add a simple property and value (message = Hello world) to the newly created a-bootiful-client.properties file and then git commit the change.

Specify the path to the Git repository by specifying the spring.cloud.config.server.git.uri property in configuration-service/src/main/resources/application.properties. You must also specify a different server.port value to avoid port conflicts when you run both this server and another Spring Boot application on the same machine. The following listing (from configuration-service/src/main/resources/application.properties) shows such an application.properties file:

server.port=8888
spring.cloud.config.server.git.uri=/Users/ziameraj16/study/JCG/dynamic-configuration

Now that we have set-up a Config Server, we need to set-up a new Spring Boot application that uses the Config Server to load its own configuration and that refreshes its configuration to reflect changes to the Config Server on-demand, without restarting the JVM.

To do so, add the org.springframework.cloud:spring-cloud-starter-config dependency, to connect to the Config Server. Spring sees the configuration property files, as it would any property file loaded from application.properties or application.yml or any other PropertySource.

The properties to configure the Config Client must necessarily be read in before the rest of the application’s configuration is read from the Config Server, during the bootstrap phase. Specify the client’s spring.application.name as a-bootiful-client and the location of the Config Server (spring.cloud.config.uri) in configuration-client/src/main/resources/bootstrap.properties, where it will be loaded earlier than any other configuration. The following listing shows that file:

configuration-client/src/main/resources/bootstrap.properties

spring.application.name=a-bootiful-client
spring.cloud.config.uri=http://localhost:8888

You also want to enable the /refresh endpoint, to demonstrate dynamic configuration changes. The following listing (from configuration-client/src/main/resources/application.properties) shows how to do so:

management.endpoints.web.exposure.include=*

The client can access any value in the Config Server by using the traditional mechanisms (such as @ConfigurationProperties or @Value("${…​}") or through the Environment abstraction). Now you need to create a Spring MVC REST controller that returns the resolved message property’s value.

6. Testing

You can test the end-to-end result by starting the Config Service first and then, once it is running, starting the client. Visit the client app in the browser at http://localhost:8080/message. There, you should see Hello world in the response.

7. Summary

In this article, we learned about the Dynamic Configuration. We discussed the advantages of dynamic configurations and how to implement this using Spring Cloud. We looked at the Spring Cloud Server and the Client configurations needed to achieve dynamic behavior.

Mohammad Meraj Zia

Senior Java Developer
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button