通过总线机制实现自动刷新客户端配置(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 配置中心
一.概述 什么是配置中心呢,在基于微服务的分布式系统中,每个业务模块都可以拆分成独立自主的服务,由多个请求来协助完成某个需求,那么在某一具体的业务场景中,某一个请求需要调用多个服务来完成,那么就存在一 ...
随机推荐
- python笔记(3)---列表
lst = ["bob","jack","马云","马化腾","王健林"] del lst[1:3] ...
- 最简单的注册美区Apple ID方法
最简单方法注册苹果美区Apple ID 1.打开苹果官网链接 苹果官网 2. 点击右下角的 United States 3. 点击图片中的选项 4.点击右上角的选项创建新的Apple ID 注意是新的 ...
- 51nod1730 涂边
题目描述 题解 八级sb题 显然可以想到状压 枚举当前的宽度\(I\),设\(f[s]\)表示在当前的宽度下选的竖边的状态为s 再设\(g[s1][s2]\)表示状态s1转移到s2的方案数,枚举中间横 ...
- qt学习(一)qt三个文件函数的框架
学到点什么, 而不是复制着什么, 每天敲着别人给的代码,苦涩得改完bug, 就这样一天天的过去, 实质上并没有学到什么, 别人的思想只是拿来借鉴, 你的思想是好是坏都是你的, 不用急着抛弃自己. 从q ...
- 百度小程序 配置 app.json 文件
可以通过配置 app.json 文件,设置 SWAN 的界面.路径.多 TAB 等. app.json 配置项列表如下 属性 类型 必填 描述 pages Array.<string> 是 ...
- Ajax中浏览器的缓存问题解决方法
我们在做项目中,一般提交请求都会通过ajax来提交,但是测试的时候发现,每次提交后得到的数据都是一样的,调试可以排除后台代码的问题,所以问题肯定是出在前台 每次清除缓存后,就会得到一个新的数据,所以归 ...
- input el-input 只能输入正整数验证
字母e在js中属于数字,所以一般的正则匹配 \d 是拦不住字母e 的 正确写法为: onKeypress="return (/[\d]/.test(String.fromCharCode(e ...
- TestingWhiz社区版2013版下载地址
TestingWhiz社区版 https://sourceforge.net/projects/testingwhiz-community-edition/ https://sourceforge.n ...
- Redis的消息订阅/发布 Utils工具类
package cn.cicoding.utils; import org.json.JSONException; import org.json.JSONObject; import redis.c ...
- navigation ObtacleCostFunction源码分析
ObtacleCostFunction 定义了一个ObstacleCostFunction类,继承自Trajectory类,Trajectory类有8个类参 总共有8个类参 double xv_,yv ...