通过总线机制实现自动刷新客户端配置(Consul,Spring Cloud Config,Spring Cloud Bus)
通过总线机制实现自动刷新客户端配置
方案示意图

利用Git服务的webhook通知功能,在每次更新配置之后,Git服务器会用POST方式调用配置中心的/actuator/bus-refresh接口,配置中心的总线服务会将此事件广播给加入总线的所有客户端,客户端收到事件后会从新读取配置中心的内容。
增加POM依赖
配置中心的服务端(spring-cloud-config-server)和客户端(spring-cloud-config-client)都加入Spring Cloud Bus引用包:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
启动Rabbitmq
docker pull rabbitmq:3-management
docker run -d --hostname my-rabbit --name rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3-management
可以访问127.0.0.1:15672/登录rabbitmq管理监控后台,用户名密码都是guest/guest。
修改配置信息
配置中心的服务端(spring-cloud-config-server)和客户端(spring-cloud-config-client)都需要修改配置文件的内容:
spring-cloud-config-server项目的application.properties增加:
# 开启消息跟踪
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
#显示的暴露接入点
management.endpoints.web.exposure.include=*
spring-cloud-config-client项目的application.properties增加:
# 开启消息跟踪
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
#显示的暴露接入点
management.endpoints.web.exposure.include=*
spring-cloud-config-client项目的bootstrap.properties增加(否则会报错:A component required a bean named 'configServerRetryInterceptor' that could):
spring.cloud.config.fail-fast=true
配置Git的Webhook



192.168.0.21:9004/actuator/bus-refresh是我一个配置中心的地址,如果有多个配置中心可以写多个webhook,在页面上测试中如果返回204就说明成功了。
将Webhook的POST请求中的body清空
Git在进行webhood post请求的同时默认会在body加上这么一串载荷(payload),Spring Boot 无法并行化,所以在配置中心服务端(spring-cloud-config-server)新建下面两个类:
此代码参考了:spring_cloud config 配置中心及利用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;
//清空请求中的Body
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在进行webhood post请求的同时默认会在body加上这么一串载荷(payload),Spring Boot 无法并行化。
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());
//只过滤/actuator/bus-refresh请求
if (!url.endsWith("/bus-refresh")) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
//使用HttpServletRequest包装原始请求达到修改post请求中body内容的目的
EmptyRequestWrapper requestWrapper = new EmptyRequestWrapper(httpServletRequest);
filterChain.doFilter(requestWrapper, servletResponse);
}
@Override
public void destroy() {
}
}
最后在启动类上添加@ServletComponentScan注解
@SpringBootApplication
//启动配置中心
@EnableConfigServer
//启动服务发现
@EnableDiscoveryClient
@ServletComponentScan
public class SpringCloudConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudConfigServerApplication.class, args);
}
}
测试自动刷新自动
访问客户端程序127.0.0.1:9006/ConfigTest,得到当前结果Test-8,访问配置中心也是Test-8:


我们更新Git参考将配置内容改为Test-9:


查看配置中心127.0.0.1:9004/ConfigDepot/Test,内容已经改为Test-9,再刷新客户端程序127.0.0.1:9006/ConfigTest,这时配置内容已经成功改成了Test-9,总线事件通知客户端刷新配置成功。


从配置中心服务端和客户端的日志也可看出刷新配置信息的过程:


源码
Github仓库:https://github.com/sunweisheng/spring-cloud-example
通过总线机制实现自动刷新客户端配置(Consul,Spring Cloud Config,Spring Cloud Bus)的更多相关文章
- 手动刷新客户端配置内容(Spring Cloud Config)
手动刷新客户端配置内容 客户端项目增加依赖项 <dependency> <groupId>org.springframework.boot</groupId> &l ...
- 实现SpringCloud Config 客户端自动刷新
文章来源:https://blog.csdn.net/qq_27385301/article/details/82716218 一.简介 在使用SpringCloud Config客户端时,如果Con ...
- config配置中心之自动刷新
自动刷新(自动刷新是基于springcloudbus来实现的,springcloud bus是基于rabbitMQ或者Kafka来实现的) Spring Cloud Bus 将分布式的节点用轻量的消息 ...
- webpack学习(三)之web-dev-server不能自动刷新问题
使用webpack-dev-server中遇到不能浏览器无法自动刷新的问题:寻找多方答案后明白了一些: 下面有一些需要注意的点: 1.webpack-dev-server并不能读取你的webpack. ...
- springboot+cloud 学习(五)统一配置中心 spring cloud config + cloud bus + WebHooks +RibbitMQ
前言 微服务要实现集中管理微服务配置.不同环境不同配置.运行期间也可动态调整.配置修改后可以自动更新的需求,Spring Cloud Config同时满足了以上要求.Spring Cloud Conf ...
- Spring Boot + Spring Cloud 构建微服务系统(九):配置中心(Spring Cloud Config)
技术背景 如今微服务架构盛行,在分布式系统中,项目日益庞大,子项目日益增多,每个项目都散落着各种配置文件,且随着服务的增加而不断增多.此时,往往某一个基础服务信息变更,都会导致一系列服务的更新和重启, ...
- Spring Cloud Config(一):聊聊分布式配置中心 Spring Cloud Config
目录 Spring Cloud Config(一):聊聊分布式配置中心 Spring Cloud Config Spring Cloud Config(二):基于Git搭建配置中心 Spring Cl ...
- Spring Cloud Config 分布式配置中心【Finchley 版】
一. 介绍 1,为什么需要配置中心? 当服务部署的越来越多,规模越来越大,对应的机器数量也越来越庞大,靠人工来管理和维护服务的配置信息,变得困难,容易出错. 因此,需要一个能够动态注册和获取服务信息的 ...
- Spring Cloud09: Config 配置中心
一.概述 什么是配置中心呢,在基于微服务的分布式系统中,每个业务模块都可以拆分成独立自主的服务,由多个请求来协助完成某个需求,那么在某一具体的业务场景中,某一个请求需要调用多个服务来完成,那么就存在一 ...
随机推荐
- 前端之CSS:属性操作2
css样式之属性操作 一.文本属性 1.text-align:cnter 文本居中2.line heigth 垂直居中 :行高,和高度对应3.设置图片与文本的距离:vertical-align4.te ...
- 【leetcode】1124. Longest Well-Performing Interval
题目如下: We are given hours, a list of the number of hours worked per day for a given employee. A day i ...
- python frozenset集合(17)
在前一篇文章中我们对 python set集合 做了详细的讲解,而本文讲解的 frozenset集合 其实和set集合类似!区别在于frozenset集合不能修改/添加/删除,其他功能和set集合一样 ...
- mysql RIGHT JOIN关键字 语法
mysql RIGHT JOIN关键字 语法 作用:RIGHT JOIN 关键字会右表 (table_name2) 那里返回所有的行,即使在左表 (table_name1) 中没有匹配的行.惠州大理石 ...
- PHP文件的上传和下载
1.使用PHP的创始人 Rasmus Lerdorf 写的APC扩展模块来实现(http://pecl.php.net/package/apc) APC实现方法: 安装APC,参照官方文档安装,可以使 ...
- 基于Cesium的Web3d实现二三维室内外一体化融合
https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/index.html?src=3D%20Models.html 三维建模 BIM
- [BZOJ1478&1488&1815][SGU282]Isomorphism:Polya定理
分析 三倍经验题,本文以[BZOJ1478][SGU282]Isomorphism为例展开叙述,主体思路与另外两题大(wan)致(quan)相(yi)同(zhi). 这可能是博主目前写过最长也是最认真 ...
- 学习wavenet_vocoder之环境配置
WaveNet vocoder位于github的位置,https://github.com/r9y9/wavenet_vocoder 一.配置时的环境 操作系统:win10 python环境工具:An ...
- [CSP-S模拟测试]:小P的单调数列(树状数组+DP)
题目描述 小$P$最近喜欢上了单调数列,他觉得单调的数列具有非常多优美的性质.经过小$P$复杂的数学推导,他计算出了一个单调增数列的艺术价值等于该数列中所有书的总和.并且以这个为基础,小$P$还可以求 ...
- 【转】SQL Pretty Printer for SSMS 很不错的SQL格式化插件
源地址:https://www.cnblogs.com/leospace/archive/2012/09/04/SQL_Pretty_Printer_for_SSMS.html 写SQL语句或者脚本时 ...