Skip to main content

Distributed Configuration

In a monolith, application.properties is fine. In microservices, changing a DB password in 50 services means 50 redeployments. We need Externalized Configuration.

1. Spring Cloud Config Server

This server connects to a Git repository (or filesystem) where your config files live, and serves them to microservices via an HTTP API. Setup Server:
  1. Dependency: spring-cloud-config-server.
  2. Annotation: @EnableConfigServer.
  3. application.yml:
server:
  port: 8888

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/my-org/config-repo
          default-label: main
The Config Repo: Create a git repo with files:
  • user-service.yml
  • order-service.yml
  • application.yml (Global config shared by all)

2. Config Client

The microservice that consumes the config.
  1. Dependency: spring-cloud-starter-config.
  2. Bootstrap phase: The app needs to know where the Config Server is before it starts up fully.
Create src/main/resources/application.yml (Or bootstrap.yml in older versions):
spring:
  application:
    name: user-service
  config:
    import: "optional:configserver:http://localhost:8888/"
Now, when user-service starts, it fetches configuration from the Config Server.

3. Profiles

You can have user-service-dev.yml and user-service-prod.yml in your git repo. Run your app with: java -jar app.jar --spring.profiles.active=prod It will fetch the prod config automatically.

4. Dynamic Refresh (Hot Reload)

What if you change a property in Git and want to apply it without restarting the service?
  1. Add spring-boot-starter-actuator dependency.
  2. Add @RefreshScope on the bean holding the config.
@RestController
@RefreshScope
public class TestController {

    @Value("${custom.feature-flag}")
    private boolean featureEnabled;

    @GetMapping("/feature")
    public boolean isEnabled() {
        return featureEnabled;
    }
}
  1. Enable the refresh endpoint in application.yml:
management:
  endpoints:
    web:
      exposure:
        include: refresh
  1. Trigger the refresh: POST http://localhost:8080/actuator/refresh
Spring will re-fetch the config and re-initialize beans marked with @RefreshScope.