Learnitweb

Refresh configurations at runtime using Spring Cloud Bus

1. Introduction

If you have followed the tutorials till now, we set up our microservices with config server. But the problem with this approach. Whenever we want to refresh the configurations at runtime without restart, we have to invoke the refresh API for each microservice instance. To oversome this challenge we can use Spring Cloud Bus. Spring Cloud Bus links all the nodes of a distributed system with a lightweight message broker and this can be used to broadcast the state changes, for example, configuration changes. Behind the scenes, the Spring Cloud Bus is going to interlink all your microservices instances with a lightweight message broker like RabbitMQ and Kafka.

With this approach, the advantage is that you only need to call the bus refresh API endpoint on one instance via the actuator. If you have 500 instances running in production, you don’t need to invoke the actuator refresh API on each of them individually. Instead, you can invoke the bus refresh API on any one of the 500 instances. Spring Cloud Bus will then handle propagating the changes from the Spring Cloud Config Server to all other instances that are connected to the same message broker, such as RabbitMQ.

2. Running RabbitMQ

In this tutorial, we’ll use RabbitMQ as the message broker. The best way to get started with RabbitMQ is to run it as a Docker image. You can use the following command:

docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:4.0-management

3. Update microservice instances

Add the following dependency in all microservice instances:

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-bus-amqp</artifactId>
		</dependency>

In each of the microservice instances, add the following configuration:

  rabbitmq:
    host: "localhost"
    port: 5672
    username: "guest"
    password: "guest"

Following is the complete application.yml file for one of the microservice instances.

spring:
  application:
    name: service2
  profiles:
    active: prod
  config:
    import: "optional:configserver:http://localhost:8085?fail-fast=true&max-attempts=10&max-interval=1500&multiplier=1.2&initial-interval=1100"
  rabbitmq:
    host: "localhost"
    port: 5672
    username: "guest"
    password: "guest"
management:
  endpoints:
    web:
      exposure:
        include: "*"
server:
  port: 8082

4. Test your changes

Once all the changes are done, we can test our changes.

  • Restart you config server and config clients.
  • Update the properties in GitHub. We have updated the service1-prod.yml and service2-prod.yml for message.
  • Now hit the /actuator/busrefresh endpoint in any of the microservice instance. For example:
    POST localhost:8080/actuator/busrefresh
  • Now verify that the configuration is changed for all microservices.

5. Summary

Below are the steps to refresh configurations at runtime using Spring Cloud Bus:

  • Add actuator dependency in the Config Server and Client Services. Add Spring Boot actuator dependency in the pom.xml of each microservices to expose /actuator/busrefresh endpoint.
  • Enable busrefresh api. The Spring Boot actuator library provides a configuration endpoint called actuator/busrefresh that can trigger a refresh event. By default, this endpoint is not exposed. You need to enable it in the application.yml file using the below config:
management:
  endpoints:
    web:
      exposure:
        include: busrefresh
  • Add Spring Cloud Bus dependency in the Config Server and Client services. Add Spring Cloud Bus dependency (spring-cloud-starter-bus-amqp) inside pom.xml on the microservices.
  • Set up RabbitMQ. Run RabbitMQ service and configure RabbitMQ connection details in the application.yml file of Config Server and Client Services.

5. Refresh configurations at runtime using Spring Cloud Bus & Spring Cloud Config Monitor

Spring Cloud Config includes the Monitor library, which streamlines the process of triggering configuration change events in the Config Service. By exposing the /monitor endpoint, this library enables seamless propagation of configuration updates to all subscribed applications through the Spring Cloud Bus.

The Monitor library supports integration with popular version control platforms like GitHub, GitLab, and BitBucket. By configuring webhooks in these services, you can automate the process of notifying the Config Service. Whenever changes are pushed to the configuration repository, the webhook sends a POST request to the /monitor endpoint, ensuring updated configurations are automatically distributed to all connected applications.

Following are the steps:

  • Add actuator dependency in the Config server and Client services. Add Spring Boot Actuator dependency inside pom.xml of the individual microservices and Config server to expose the /busrefresh endpoint.
  • Enable /busrefresh API. The Spring Boot Actuator library provides a configuration endpoint /actuator/busrefresh that can trigger a refresh event. By default, this endpoint is not exposed. You need to manually enable this.
management:
  endpoints:
    web:
      exposure:
        include: busrefresh
  • Add Spring Cloud Bus dependency in the Config Server and Client services. Add Spring Cloud Bus dependency (spring-cloud-starter-bus-amqp) inside pom.xml of each microservice and Config server.
  • Add Spring Cloud Config monitor dependency in Config server. Add Spring Cloud Config monitor dependency (spring-cloud-config-monitor) inside pom.xml of Config server and this exposes /monitor endpoint.
  • Set up RabbitMQ. Set up the RabbitMQ service. Then configure the RabbitMQ connection details in the application.yml of Config server and Config client.
  • Set up a webhook in GitHub. Set up a webhook in GitHub to automatically send a POST request to /monitor endpoint after every push to the repository.