Auto-refresh client configuration via bus mechanism
Schema Diagram
With the webhook notification function of the Git service, after each configuration update, the Git server invokes the/actuator/bus-refresh interface of the Configuration Center by POST. The bus service of the Configuration Center broadcasts this event to all clients joining the bus, and the client reads the content of the Configuration Center from scratch when it receives the event.
Increase POM dependency
Both the server (spring-cloud-config-server) and client (spring-cloud-config-client) of the configuration center join the Spring Cloud Bus reference package:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
Start Rabbitmq
docker pull rabbitmq:3-management docker run -d --hostname my-rabbit --name rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3-management
You can access 127.0.0.1:15672/login rabbitmq administration monitoring background, the username password is guest/guest.
Modify configuration information
Both the server (spring-cloud-config-server) and the client (spring-cloud-config-client) of the configuration center need to modify the contents of the configuration file:
application.properties for the spring-cloud-config-server project increased:
# Turn on message tracking spring.cloud.bus.trace.enabled=true spring.rabbitmq.host=127.0.0.1 spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest #Exposed Access Points Displayed management.endpoints.web.exposure.include=*
application.properties for the spring-cloud-config-client project increased:
# Turn on message tracking spring.cloud.bus.trace.enabled=true spring.rabbitmq.host=127.0.0.1 spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest #Exposed Access Points Displayed management.endpoints.web.exposure.include=*
The bootstrap.properties for the spring-cloud-config-client project is increased (otherwise an error will be reported: A component required a bean named'configServerRetryInterceptor'that could):
spring.cloud.config.fail-fast=true
Configure Git's Webhook
192.168.0.21:9004/actuator/bus-refresh is the address of one of my configuration centers. If there are multiple configuration centers that can write multiple webhook s, returning 204 in the page test indicates success.
Empty the body in the POST request for Webhook
Git makes webhood post requests by default with such a payload on the body that Spring Boot cannot be parallelized, so create the following two new classes on the spring-cloud-config-server side of the configuration center:
This code refers to: spring_cloud config configuration center and automated hot load configuration using Github
import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.ByteArrayInputStream; import java.io.IOException; //Empty Body in Request public class EmptyRequestWrapper extends HttpServletRequestWrapper{ public EmptyRequestWrapper(HttpServletRequest request) { super(request); } @Override public ServletInputStream getInputStream() throws IOException { byte[] bytes = new byte[0]; ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); return new ServletInputStream() { @Override public boolean isFinished() { return byteArrayInputStream.read() == -1 ? true:false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener readListener) { } @Override public int read() throws IOException { return byteArrayInputStream.read(); } }; } }
import org.springframework.core.annotation.Order; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import java.io.IOException; @WebFilter(filterName = "bodyFilter", urlPatterns = "/*") @Order(1) //Git makes a webhood post request with such a payload by default that Spring Boot cannot be parallelized. public class BusRefreshFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest; String url = new String(httpServletRequest.getRequestURI()); //Filter/actuator/bus-refresh requests only if (!url.endsWith("/bus-refresh")) { filterChain.doFilter(servletRequest, servletResponse); return; } //Wrap the original request using HttpServletRequest to modify the body content in the post request EmptyRequestWrapper requestWrapper = new EmptyRequestWrapper(httpServletRequest); filterChain.doFilter(requestWrapper, servletResponse); } @Override public void destroy() { } }
Finally, add the @ServletComponentScan annotation on the startup class
@SpringBootApplication //Start Configuration Center @EnableConfigServer //Start Service Discovery @EnableDiscoveryClient @ServletComponentScan public class SpringCloudConfigServerApplication { public static void main(String[] args) { SpringApplication.run(SpringCloudConfigServerApplication.class, args); } }
Test Auto Refresh Auto
Access the client program 127.0.0.1:9006/ConfigTest, get the current result Test-8, access the Configuration Center is also Test-8:
We updated the Git reference to change the configuration to Test-9:
Check Configuration Center 127.0.0.1:9004/ConfigDepot/Test, the content has been changed to Test-9, and then refresh the client program 127.0.0.1:9006/ConfigTest, when the configuration content has been successfully changed to Test-9, bus events notify the client that the configuration has been refreshed successfully.
The process of refreshing configuration information can also be seen from the logs of the configuration center's servers and clients:
Source code
Github repository: https://github.com/sunweisheng/spring-cloud-example