带你入门SpringCloud 之 通过SpringCloud Bus 自动更新配置

前言

《带你入门SpringCloud统一配置 | SpringCloud Config》中通过 SpringCloud Config 完成了统一配置基础环境搭建,但是并没有实现配置修改自动更新的操作(GitHub 或Gitee 修改配置后,需要重启配置服务才能更新配置)。

本文是《带你入门SpringCloud统一配置 | SpringCloud Config》的续篇,通过 SpringCloud Bus 完成配置修改自动更新的操作介绍。

阅读本文前需要你先移步《带你入门SpringCloud统一配置 | SpringCloud Config》因为本文是在其基础上进行讲解的。

另外需要你熟悉 SpringBoot 项目的基本使用即可,还有一点需要注意的是在操作过程中尽量和我本地环境一致,因为环境不一致可能会带来一些问题。我本地环境如下:

  • SpringBoot Version: 2.1.0.RELEASE
  • SpringCloud Version: Greenwich.RELEASE
  • Apache Maven Version: 3.6.0
  • Java Version: 1.8.0_144
  • IDEA:Spring Tools Suite (STS)

接下来就开始 SpringCloud Bus 环境搭建操作介绍!

SpringCloud Bus 环境搭建

第一步:安装并启用 RabbitMQ,这里就不做详细介绍了。可以查看之前的总结:Windows 环境安装 RabbitMQ

如果你的 RabbitMQ和 Config Server 端不在一台机器上,或者端口、用户名、密码不是使用的默认配置,那么你需要进行如下配置在 Config Server 端 application.properties 中

spring.rabbitmq.host=rabbitmq 服务IP地址
spring.rabbitmq.port=rabbitmq 服务端口号
spring.rabbitmq.username=rabbitmq 服务用户名
spring.rabbitmq.password=rabbitmq 服务密码

第二步:在 Config Server 端端和客户端都引入 spring-cloud-starter-bus-amqp 依赖。具体代码如下:

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

第三步:在Config Server 端的 application.properties 中需要添加如下配置,目的是把刷新配置接口暴露出来,具体配置如下:

management.endpoints.web.exposure.include=  *

第四步:Config Client 端引入openfeign starter 依赖,具体代码如下:

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

第五步:验证 Config Server 端和 Config Client 端是否在 RabbitMQ 注册队列和是否注册到 Eureka Server 端上。如下图所示:

需要先启动 Eureka Server 服务端,然后在依次启动 Config Server端和Config Client端。



第六步:Config Client 端上访问配置的 Controller 声明刷新配置作用域@RefreshScope。具体代码如下:

@RestController
@RefreshScope
public class EvnController {
    @Value("${env}")
    private String env;

    @RequestMapping("/env")
    public String evn() {
        return this.env;
    }
}

不添加 @RefreshScope注解,配置更新后不会生效。
如果是自定义前缀配置需要在@ConfigurationProperties下添加 @RefreshScope即可,

最七步在 Gitee 上配置 WebHooks,具体操作方式如下图所示:

进入Gitee 点击管理,然后点击 WebHooks。


点击添加按钮添加新的 WebHooks 设置。

输入本地映射外网访问域名+/actuator/bus-refresh,自己测试可以使用 NATAPP 进行内网穿穿透配置。具体配置请查看 https://natapp.cn/。

测试

手动访问更新链接进行测试

修改配置在码云远程仓库上,然后使用 PostMan 访问:http://localhost:8080/actuator/bus-refresh ,如下图所示:

这里演示直接是在码云上操作,相当于执行 git push 操作。



然后在查看商品服务(Config Client端)配置是否生效。如下图所示自动更新成功!

WebHooks 测试

进入 WebHooks 设置,然后点击测试。会报如下图所示错误:

解决方案:

参考来CSDN 作者 tinysakurac 解决方案。
文章:《解决使用spring cloud config bus使用webhook自动刷新出现的400问题》 (https://blog.csdn.net/m0_37556444/article/details/82812816)

问题产生原因:GitHub在进行 POST 请求的同时默认会在 Body 加上这么一串载荷(payload),而 /actuator/bus-refresh 接口没有进行接受这些信息处理,所以就报错了。

解决问题思路:通过拦截器拦截 bus-refresh请求,然后在 HttpServletRequestMapper 包装类将 Request中 Body 内容置空。具体代码如下:

拦截 bus-refresh请求Filter 类。

public class BusRefreshFilter implements Filter{

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest)request;
        String url = new String(httpServletRequest.getRequestURI());
        //只过滤/actuator/bus-refresh请求
        if (!url.endsWith("/bus-refresh")) {
            chain.doFilter(request, response);
            return;
        }
        //使用HttpServletRequest包装原始请求达到修改post请求中body内容的目的
        CustometRequestWrapper requestWrapper = new CustometRequestWrapper(httpServletRequest);
        chain.doFilter(requestWrapper, response);
    }
}

自定义 HttpServletRequestWrapper 类

public class CustometRequestWrapper extends HttpServletRequestWrapper{

    public CustometRequestWrapper(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();
            }

        };
    }
}

将拦截 bus-refresh请求Filter 添加到 Spring 上下文中配置类。

@Configuration
public class FilterConfig {
     @Bean
        public FilterRegistrationBean<BusRefreshFilter> filterRegistration() {
            FilterRegistrationBean<BusRefreshFilter> registration = new FilterRegistrationBean<BusRefreshFilter>();
            registration.setFilter(new BusRefreshFilter());
            List<String> urlList = new ArrayList<String>();
            urlList.add("/*");
            registration.setUrlPatterns(urlList);
            registration.setName("BusRefreshFilter");
            registration.setOrder(1);
            return registration;
        }
}

然后修改Gitee 上的配置信息后就可以自动更新了,这里就不在进行演示操作来。

还有一种方式是通过访问 Config Server端域名/monitor 来取代 Config Server端域名//actuator/bus-refresh。本方式个人尝试没有成功!具体配置官网介绍如下:

Many source code repository providers (such as Github, Gitlab, Gitea, Gitee, Gogs, or Bitbucket) notify you of changes in a repository through a webhook. You can configure the webhook through the provider’s user interface as a URL and a set of events in which you are interested. For instance, Github uses a POST to the webhook with a JSON body containing a list of commits and a header (X-Github-Event) set to push. If you add a dependency on the spring-cloud-config-monitor library and activate the Spring Cloud Bus in your Config Server, then a /monitor endpoint is enabled.

在Config Server 添加 spring-cloud-config-monitor 依赖

<dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-config-monitor</artifactId>
</dependency>

然后在Config Client 添加如下配置:
参考:https://github.com/spring-cloud/spring-cloud-bus/issues/124

spring.cloud.bus.id=${vcap.application.name:${spring.application.name:application}}:${vcap.application.instance_index:${spring.profiles.active:${local.server.port:${server.port:0}}}}:${vcap.application.instance_id:${random.value}}

小结

当将远程仓库配置文件修改后,通过GitHub 或者 Gitee 的 WebHooks 配置自动访问接口bus-refresh 来通知Config Server 端。

Config Server 端收到请求后将配置 clone 下来,然后通过消息队列(默认是RabbitMQ)将修改后的配置发送给 Config Client 端。Config Client 端收到消息后重新从Config Server 端获取最新的配置信息。

而WebHooks 配置请求接口 bus-refresh 和消息队列发送配置给 Config Client 端都是 SpringCloud Bus 帮助我们完成的。

代码示例

如果你按照上述方式搭建并未成功,可以参考我在GitHub 项目 spring-cloud-get-started 仓库中模块名为:

spring-cloud-config-eureka-service
spring-cloud-config-server
spring-cloud-config-product-service
进行对比查看是否配置有误。

spring-cloud-get-started 项目地址:https://github.com/zhuoqianmingyue/spring-cloud-get-started

参考文献

https://blog.csdn.net/m0_37556444/article/details/82812816 By tinysakurac

https://cloud.spring.io/spring-cloud-config/reference/html/

原文地址:https://www.cnblogs.com/jerry126/p/11621334.html

时间: 2024-07-29 20:51:32

带你入门SpringCloud 之 通过SpringCloud Bus 自动更新配置的相关文章

spring cloud 使用spring cloud bus自动刷新配置

Spring Cloud Bus提供了批量刷新配置的机制,它使用轻量级的消息代理(例如RabbitMQ.Kafka等)连接分布式系统的节点,这样就可以通过Spring Cloud Bus广播配置的变化或者其他的管理指令.使用Spring Cloud Bus后的架构如图9-2所示. 图9-2 使用Spring Cloud Bus的架构图 由图可知,微服务A的所有实例通过消息总线连接到了一起,每个实例都会订阅配置更新事件.当其中一个微服务节点的/bus/refresh端点被请求时,该实例就会向消息总

SpringCloud(一).大话SpringCloud

学习一个东西,首先要搞清楚这个东西是什么,有什么用,怎么用.最近会坚持写博客,将最近学习的SpringCloud的过程记录下来,很多东西往往看了一遍过一段时间就会遗忘,用博客记录下来是一个很好的方式,在整理的过程中才能查漏补缺,知道自己哪些地方掌握的不牢,哪些地方可能是之前学习没有想到的地方.  一.什么是SpringCloud 在说SpringCloud之前,不得不提一下微服务,微服务是可以独立部署,水平扩张,独立访问(或者有单独的数据库)的服务单元.当一个单体系统越来越庞大时,带来的业务逻辑

可能是史上最强大的js图表库——ECharts带你入门

PS:之前的那篇博客Highcharts——让你的网页上图表画的飞起 ,评论中,花儿笑弯了腰 和 StanZhai 两位仁兄让我试试 ECharts ,去主页看到<Why ECharts ?>简单了解了一下之后,ECharts很快吸引了我.里面引自马云的那句话“互联网还没有搞清楚的时候,移动互联网来了,移动互联没有搞清楚的时候,大数据来了”我是第一次听到,实在震撼了我啊(孤陋寡闻...). 本来没打算写什么的.可是作为一个后端开发者,看了半天文档也迷迷糊糊,查了一堆资料也没搞懂Echarts那

我在爱板网写的-- 【望月追忆】带你入门STM32F0系列文章

[望月追忆]带你入门STM32F0之前传:STM32F0资料 [望月追忆]带你入门STM32F0之环境搭建 [望月追忆]带你入门STM32F0之一:STM32F0概述 [望月追忆]带你入门STM32F0之二:SysTick时钟介绍 [望月追忆]带你入门STM32F0之二:点亮你的小灯 [望月追忆]带你入门STM32F0之三:按键----查询方式 [望月追忆]带你入门STM32F0之四:按键----外部中断 [望月追忆]带你入门STM32F0之四:串口 [望月追忆]带你入门STM32F0之五:小项

史上最强大的js图表库——ECharts带你入门(转)

出处:http://www.cnblogs.com/zrtqsk/p/4019412.html PS:之前的那篇博客Highcharts——让你的网页上图表画的飞起 ,评论中,花儿笑弯了腰 和 StanZhai 两位仁兄让我试试 ECharts ,去主页看到<Why ECharts ?>简单了解了一下之后,ECharts很快吸引了我.里面引自马云的那句话“互联网还没有搞清楚的时候,移动互联网来了,移动互联没有搞清楚的时候,大数据来了”我是第一次听到,实在震撼了我啊(孤陋寡闻...). 本来没打

手把手带你入门神秘的RxJava

1.什么是RxJava? Rx是Reactive Extensions的简写,翻译为响应的扩展.也就是通过由一方发出信息,另一方响应信息并作出处理的核心框架代码.? 该框架由微软的架构师Erik Meijer领导的团队开发,并在2012年11月开源.? Rx库支持.NET.JavaScript和C++等,现在已经支持几乎全部的流行编程语言了.? Rx的大部分语言库由ReactiveX这个组织负责维护,比较流行的有RxJava/RxJS/Rx.NET,社区网站是 reactivex.io.? Rx

SpringCloud学习系列-SpringCloud

SpringCloud是什么? SpringCloud=分布式微服务架构下的一站式解决方案,是各个微服务架构落地技术的集合体,俗称微服务全家桶 SpringCloud,基于SpringBoot提供了一套微服务解决方案,包括服务注册与发现,配置中心,全链路监控,服务网关,负载均衡,熔断器等组件,除了基于NetFlix的开源组件做高度抽象封装之外,还有一些选型中立的开源组件. SpringCloud利用SpringBoot的开发便利性巧妙地简化了分布式系统基础设施的开发,SpringCloud为开发

Node.js入门:Node.js&amp;NPM的安装与配置

Node.js安装与配置  Node.js已经诞生两年有余,由于一直处于快速开发中,过去的一些安装配置介绍多数针对0.4.x版本而言的,并非适合最新的0.6.x的版本情况了,对此,我们将在0.6.x的版本上介绍Node.js的安装和配置.(本文一律以0.6.1为例,0.6的其余版本,只需替换版本号即可.从http://nodejs.org/#download可以查看到最新的二进制版本和源代码). Windows平台下的Node.js安装 在过去,Node.js一直不支持在Windows平台下原生

Android基础入门教程——2.4.11 AutoCompleteTextView(自动完成文本框)的基本使用

Android基础入门教程--2.4.11 AutoCompleteTextView(自动完成文本框)的基本使用 标签(空格分隔): Android基础入门教程 本节引言: 本节继续来学习Adapter类的控件,这次带来的是AutoCompleteTextView(自动完成文本框), 相信细心的你发现了,和Adapter搭边的控件,都可以自己定义item的样式,是吧! 或者说每个Item的布局~想怎么玩就怎么玩~嗯,话不多说,开始本节内容~ 对了贴下官方API:AutoCompleteTextV