Spring Boot Handbook

    Microservice Advance: Refresh Configuration without Restart using Centralized Configuration

    Introduction#

    Dynamic configuration management is vital to maintaining system flexibility and efficiency in an environment of microservices. Traditionally, updating the configurations involved service downtimes where services would be started or stopped. However, with centralized configuration management, updates to configurations can be done at runtime without stopping any microservices.

    Through such a procedure, properties like database credentials, API endpoints, feature flags, and logging levels may be updated without downtime, increasing maintainability and scalability. With tools like Spring Cloud Config, Consul, or Zookeeper, microservices fetch the latest configuration and duplicate those changes across multiple instances.

    This article will discuss the implementation of refreshable configurations using a centralized config server through the use of Spring Cloud Config Server and Actuator's /refresh endpoint to enable smooth updates without downtime.

    Real-Time Analogy#

    This article compares dynamic configuration updates in microservices to a smart home system, where settings change instantly without turning off devices. Using a Config Server, @RefreshScope, and Actuator’s /refresh endpoint`, microservices can update configurations without restarting, ensuring efficiency, scalability, and real-time adaptability.

    Centralized Config Server#

    Speaking of a centralized config server, this is a service dedicated and independent in managing every configuration provided at runtime to all microservices. The configurations can be environment-specific and profile-based, thus fulfilling the need for flexibility in dev, test, and prod environments. Rather than storing configurations in each service, all microservice configurations are externalized to a central repository, say Git or a database.

    Dynamic refreshing of configuration properties will help microservices update the configurations dynamically without restarting the services, which is going to be extremely scalable and maintainable. Such tools as Spring Cloud Config can easily integrate with other systems, providing a very safe, consistent, and efficient method of configuration management for a microservices architecture.

    Refresh Scope (@RefreshScope)#

    Spring Cloud will allow you to make the @RefreshScope annotation that enables an application to refresh a bean anytime in its lifetime, mainly due to configuration changes. The configuration changes can be applied this way without restarting the whole application. It is primarily used in conjunction with Spring Cloud Config, which provides externalized configuration management to the microservices.

    Key Features#

    • Dynamic Bean Refresh: Beans annotated with @RefreshScope are updated automatically when configurations are changed.
    • Who Needs to Restart: No more microservice restarts to apply new configurations.
    • Actuator Support: Works with the Spring Boot Actuator /refresh endpoint, allowing for run-time refresh via HTTP requests.

    How Does It Work?#

    A microservice fetches configuration data from the Spring Cloud Config Server. If modifications are done to the configurations stored in the repository, a /refresh request will invoke the updates. Beans with the annotation @RefreshScope reload the latest values dynamically.

    Enable Actuator Endpoint#

    The /refresh endpoint in Spring Boot Actuator provides dynamic configuration updates without restarting the microservice. It is part of Spring Cloud Actuator, which works alongside Spring Cloud Config in refreshing application properties at runtime.

    Steps to Enable /refresh Endpoint (for Config Clients):#

    Add Actuator Dependency (if not already included): To dynamically refresh configurations without restarting the service, add Spring Actuator in pom.xml:

    <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
    • Enable the /refresh Endpoint in application.yml or application.properties:
    management: endpoints: web: exposure: include: refresh
    • Trigger Configuration Refresh Manually:
    import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; @RestController @RequestMapping("/products") @RefreshScope public class ProductsController { @Value("${my.variable}")// Fetching property from Config Server private String message; @GetMapping("/config") public String getConfigMessage() { return "Config Message: " + message; } }

    After updating configurations in the Config Server, notify the microservice to refresh its properties by sending a POST request:

    POST : http://localhost:<the service port>/<service contex-path>/actuator/refresh

    This triggers the /refresh endpoint, allowing the application to fetch updated configurations dynamically without a restart.

    How does it work#

    Using the term @RefreshScope allows Spring to dynamically proxy the bean for refreshing it each time a change in the configuration is detected.

    Behind the Scenes:#

    Creation of a Proxy Bean

    Spring wraps beans annotated with @RefreshScope into a proxy instead of creating a standard singleton bean. The proxy is just an actual bean reference.

    It will trigger a refresh:

    POST /actuator/refresh, Spring reloads configuration with updates from the Config Server. The old bean instance will be discarded by Spring, and a new one will be created according to the latest values.

    Least Effect in Application:

    Refreshing only marked beans of @RefreshScope without any effort to restart the entire application context. This certainly minimizes the overhead to cover the portions that are updated.

    Noted: Config refresh allows microservices to update configurations dynamically without requiring a restart, ensuring zero downtime and real-time adaptability. By using a Centralized Config Server, @RefreshScope, and Spring Boot’s /refresh endpoint, services can instantly apply changes like feature toggles, API keys, or database settings, improving scalability, efficiency, and maintainability.

    Implementation:#

    1. Add Required Dependencies#

    Required Dependency

    2. Enable Config Server in the Client Application#

     Enable Config Server

    3. Use @RefreshScope to Enable Dynamic Refresh (inside inventory-service)#

    import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; @RestController @RequestMapping("/products") @RefreshScope public class ProductsController { @Value("${my.variable}")// Fetching property from Config Server private String message; @GetMapping("/config") public String getConfigMessage() { return "Config Message: " + message; } }

    4. Without Refresh – Hit the API#

    • Main configuration (for dev)
    Configuration (for dev)

    Run the Config Client after starting the Discovery Server and Config Server (http://localhost:9020/inventory/products/config)

    • In Postman, when requesting to inventory-service without setting any active profile, it defaults to the 'dev' profile.
    Output (for dev)

    Ide Console:

    Ide logs image (for dev)
    • Change something inside dev configuration
    Some chang in github (for dev)

    Run the Config Client after starting the Discovery Server and Config Server (http://localhost:9020/inventory/products/config)

    • In Postman, when requesting to inventory-service with setting active profile defaults to the 'dev' profile.
    Output remains unchanged

    The response remains unchanged! The updated configuration has not applied yet because /refresh hasn't been triggered.

    5. Trigger Configuration Refresh Without Restart#

    **POST: http://localhost:9020/inventory/actuator/refresh**

    This triggers the /refresh endpoint, allowing the application to fetch updated configurations dynamically without a restart.

    Hit refresh api

    Run the Config Client after starting the Discovery Server and Config Server (http://localhost:9020/inventory/products/config)

    • In Postman, when requesting to inventory-service with setting active profile defaults to the 'dev' profile.
    Output changed

    Conclusion#

    The article explores how one can refresh microservice configurations without restarting, using a Centralized Config Server, @RefreshScope, and Spring Boot Actuator's /refresh endpoint. This makes scalable, maintainable, and upgradable microservices architectures even more advantageous.

    Last updated on Mar 05, 2025