
In The previous post Centralize Configurations Using Spring Cloud Config We Setup config Server and Centralized The Configuration properties in github.
In This post, We Will Check different options available to update Config properties in Client applications without restarting Them.
The code for this post is available for download here.
1 Restart Endpoint Of Spring Actuator Endpoint
The Simplest way to reload the application config without manually restarting it is Using Spring Boot Actuator Restart Endpoint.But this is not the best way to update the config.
2 Refresh Endpoint- @RefreshScope & @ConfigurationProperties
Spring allows beans to be refreshed dynamically at runtime using @RefreshScope
. The Bean That are using @Value
to read properties are need to be annotated with @RefreshScope
. The Properties loaded by @ConfigurationProperties
are automatically reloaded as @ConfigurationProperties
are by default @RefreshScope
To Reload the bean annotated with @RefreshScope
Run below post request.$ curl localhost:8090/actuator/refresh -d {} -H "Content-Type: application/json"
Problem
But Again This method has Problem, In a real microservice environment, there will be a large number of independent application services. And It is not practical for the user to manually trigger the refresh event for all the related services whenever a property is changed.Spring Bus Provide Solution For this
3 Spring Cloud Bus
Spring Cloud Bus links nodes of a distributed system with a lightweight message broker. This can then be used to broadcast state changes, The configuration changes are publised as events to all connected nodes. For the POC We will be using AMQP broker as the transport.
Our targeted architecture will look like below
Lets update the System we build in The previous post Centralize Configurations Using Spring Cloud Config
Setup RabbitMQ with Docker
We will run RabbitMQ as a docker image. Install Docker Then Run below command to install rabbitmqdocker pull rabbitmq:3-management
To Run RabbitMQ use below commanddocker run -d --hostname my-rabbit --name some-rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3-management
Verify MQ is running. http://192.168.99.100:15672/#/ (Check What IP was generated for You). Default User name and password is guest/guest.
1 | <dependency> |
Connect to MQ Bus
1 | spring.rabbitmq.host=192.168.99.100 |
Let’s Test Our Changes
- Start Config Server
- Start Multiple Instances of Customer Service.Start Customer Service on 8090,8091,8092
- Verify Config Properties http://localhost:8888/customer-service/dev
- Dev is configured as customer having gmail account as Premium Account.
- Check for http://localhost:8090/customer/niraj.sonawane@gmail.com We should get response as Premium account. Similar for 8091,8092
- Update Config properties in Github and push Changes
- Verify Updated Config Properties http://localhost:8888/customer-service/dev
- Now Check for http://localhost:8090/customer/niraj.sonawane@gmail.com We should get response as Premium account. Similar for 8091,8092. (As we have not yet refreshed anything)
- Send Bus Refresh request on 8090, http://localhost:8090/actuator/bus-refresh
- Now Check for http://localhost:8090/customer/niraj.sonawane@gmail.com We should get response as Free Account
Also Changes will be reflected for other services,Now Check for http://localhost:8091/customer/niraj.sonawane@gmail.com & http://localhost:8092/customer/niraj.sonawane@gmail.com
We have Send Bus refresh event only for 8090 But Still Changes are reflected on all nodes. Bus Will take responsibility of Sending refresh event
4 Github Webhook
Github Providers notification Event when changes are made in repository through a webhook. Github uses a POST to the webhook with a JSON body containing a list of commits and a header set to push.
Tu use Webhooks We Need to add spring-cloud-config-monitor dependency And Activate /monitor endpoint
To Add Webhooks Go to Your ConfigRepo->Settings-Webhooks. Note, You need Public Domain name for this to work.
The code for this post is available for download here.