SpringCloud学习系列之五-----配置中心(Config)和消息总线(Bus)完美使用版

前言

在上篇中介绍了SpringCloud Config的使用,本篇则介绍基于SpringCloud(基于SpringBoot2.x,.SpringCloud Finchley版)中的分布式配置中心(SpringCloud Config)的配置刷新和消息总线(RabbitMQ和Kafka)使用教程。

SpringCloud Config Refresh

在上一篇中我们介绍了springcloud配置中心的本地使用和Git使用的用法,但是当重新修改配置文件提交后,客户端获取的仍然是修改前的信息,需要客户端重启才可以获取最新的信息。因此我们需要客户端能够动态进行更新,幸好springcloud官方已经给出方案,所以我们只需要使用就行了。

开发准备

开发环境

  • JDK:1.8
  • SpringBoot:2.0.6.RELEASE
  • SpringCloud:Finchley.SR2

注:不一定非要用上述的版本,可以根据情况进行相应的调整。需要注意的是SpringBoot2.x以后,jdk的版本必须是1.8以上!

确认了开发环境之后,我们再来添加相关的pom依赖。

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
</dependencies>

服务端

服务端以及注册中心这块配置和代码和之前springcloud-config配置基本一样即可。注册中心新项目的的名称为springcloud-config-bus-eureka,服务端新项目的的名称为springcloud-config-bus-server

注册中心pom配置、application.properties配置和代码如下:

pom:

 <dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>

application.properties:

spring.application.name=springcloud-config-bus-eureka
server.port=8006
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/

代码:


    @SpringBootApplication
    @EnableEurekaServer
    public class ConfigBusEurekaApplication {

        public static void main(String[] args) {
            SpringApplication.run(ConfigBusEurekaApplication.class, args);
             System.out.println("config bus 注册中心服务启动...");
        }
    }

服务端pom配置、application.properties配置和代码如下:

pom:

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
</dependencies>

application.properties:

 spring.application.name=springcloud-config-server
 server.port=9005
 eureka.client.serviceUrl.defaultZone=http://localhost:8005/eureka/
 spring.cloud.config.server.git.uri = https://github.com/xuwujing/springcloud-study/
 spring.cloud.config.server.git.search-paths = /springcloud-config/config-repo
 spring.cloud.config.server.git.username =
 spring.cloud.config.server.git.password = 

代码:


    @EnableDiscoveryClient
    @EnableConfigServer
    @SpringBootApplication
    public class ConfigServerApplication {

        public static void main(String[] args) {
            SpringApplication.run(ConfigServerApplication.class, args);
            System.out.println("配置中心服务端启动成功!");
        }
    }
    

客户端

客户端这边在之前springcloud-config-client项目中进行改造,新项目的的名称为springcloud-config-bus-client,在pom文件中新增如下配置:

  <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

spring-boot-starter-actuator表示对该程序进行监控,可以通过http接口得到该程序的各种信息,详细的使用可以查看我的这个项目springboot-actuator,可以在注释中查询各种接口的使用。

然后再到配置文件application.properties中添加如下配置:

management.endpoints.web.exposure.include=refresh

该配置表示暴露刷新的地址为refresh。

:如果是SpringBoot1.x的版本,那么配置改成management.security.enabled=false即可。

最后在客户端的Controller增加一个@RefreshScope注解,该注解表示在接到SpringCloud配置中心配置刷新的时候,自动将新的配置更新到该类对应的字段中。


    @RestController
    @RefreshScope
    public class ClientController {

        @Value("${word}")
        private String word;

        @RequestMapping("/hello")
        public String index(@RequestParam String name) {
            return name+","+this.word;
        }
    }

测试

完成上述的代码开发后,我们来进行测试Spring-Config是否可以进行配置实时更新。
首先依次启动springcloud-config-bus-eurekaspringcloud-config-bus-serverspringcloud-config-bus-client这三个项目。其中9005是服务端springcloud-config-bus-server的端口,9006是第一个客户端springcloud-config-bus-client的端口。
启动成功之后,在浏览器输入:

http://localhost:9006//hello?name=pancm

界面返回:

pancm,hello world!!

可以正常得到服务端configtest-pro.properties的配置信息。

然后在把configtest-pro.properties的配置更改为:

word=hello 

然后我们再浏览器输入:

http://localhost:9006//hello?name=pancm

界面返回:

pancm,hello world!!

可以发现配置并没有实时的刷新,查阅官方文档得知,需要客户端通过POST方法触发各自的/refresh,所以这里我们就用Postman工具模拟post请求刷新,然后再查看信息。

使用POST请求如下地址:

http://localhost:9006/actuator/refresh

返回:

[
 "word"
]

说明完成了word配置的刷新,我们再浏览器输入:

http://localhost:9006//hello?name=pancm

界面返回:

pancm,hello 

发现已经成功实现配置刷新了!

示例图:


SpringCloud Config Bus

上述的示例中,我们客户端发现每次获取最新配置都需要手动进行刷新,如果少的的话还可以使用,但是多的话就比较繁琐了,虽然我们可以使用类似Github的WebHook的工具。

WebHook是当某个事件发生时,通过发送http post请求的方式来通知信息接收方。

但是当客户端越来越多的时候WebHook已经不好使用了,每次新增客户端都需要更改WebHook会显得很麻烦,springcloud官方给出了非常好的解决方案,Spring Cloud Bus

Spring cloud bus通过轻量消息代理连接各个分布的节点。这会用在广播状态的变化(例如配置变化)或者其他的消息指令。Spring bus的一个核心思想是通过分布式的启动器对spring boot应用进行扩展,也可以用来建立一个多个应用之间的通信频道。目前唯一实现的方式是用AMQP消息代理作为通道,同样特性的设置(有些取决于通道的设置)在更多通道的文档中。

为什么使用Spring Cloud Bus就可以解决这个问题了呢?
我们不一定非要透彻的理解其原理才可以知道,我们只需要知道它的实现步骤,就可以知道了为什么可以解决了。
步骤如下:

  1. 首先,在配置中进行更新配置文件信息,它就会自动触发post发送bus/refresh;
  2. 然后服务端就会将更新的配置并且发送给Spring Cloud Bus;
  3. 继而Spring Cloud bus接到消息之后并通知给使用该配置的客户端;
  4. 最后使用该配置的客户端收到通知后,就会获取最新的配置进行更新;

这里我也简单的画了下使用Spring Cloud Bus之前和之后的流程图,方便进行理解。

不使用Spring Cloud Bus获取配置信息流程图:

使用Spring Cloud Bus获取配置信息流程图:

开发准备

和上述的环境一样即可。

RabbitMQ 的安装教程可以看我之前写的这篇文章:RabbitMQ的环境安装及配置

Kafka 的安装教程可以看我之前写的这篇文章:kafka安装使用教程

服务端

Spring Cloud Bus 主要的使用的MQ主要使用的是,RabbitMQ和Kafka。至于使用的话就可以根据情况来进行选择,主要使用的是哪个MQ就用哪一个就行了。这里我们就用RabbitMQ作为示例来进行讲解,Kafka的使用也差不多,也无在乎配置更改而已。

首先在springcloud-config-bus-server服务端的pom文件添加如下配置:

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>

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

注: spring-boot-starter-actuator这个是必须的,不然是无法在服务端进行配置刷新请求的。如果是使用的kafka的话,只需将spring-cloud-starter-bus-amqp改成spring-cloud-starter-bus-kafka即可。

然后再到配置文件中添加如下配置:

配置信息:

spring.application.name=springcloud-config-bus-server
server.port=9005
eureka.client.serviceUrl.defaultZone=http://localhost:8006/eureka/

spring.cloud.config.server.git.uri = https://github.com/xuwujing/springcloud-study/
spring.cloud.config.server.git.search-paths = /springcloud-config/config-repo
spring.cloud.config.server.git.username =
spring.cloud.config.server.git.password = 

management.endpoints.web.exposure.include= bus-refresh
spring.cloud.bus.enabled = true
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

配置说明:

  • spring.application.name : 这个是指定服务名称。
  • server.port:服务指定的端口。
  • eureka.client.serviceUrl.defaultZone: 这个是设置与Eureka Server交互的地址,客户端的查询服务和注册服务都需要依赖这个地址。
  • spring.cloud.config.server.git.uri: 配置的Git长裤的地址。
  • spring.cloud.config.server.git.search-paths: git仓库地址下的相对地址 多个用逗号","分割。
  • spring.cloud.config.server.git.username:git仓库的账号。
  • spring.cloud.config.server.git.password:git仓库的密码。
  • management.endpoints.web.exposure.include:SpringBoot2.x之后必须添加次配置,和上述的客户端springcloud-config-bus-client增加的的配置一样,名称不一样是为了做区分。
  • spring.cloud.bus.enabled:是否启用springcloud config bus。
  • spring.cloud.bus.trace.enabled:开启跟踪总线事件。
  • spring.rabbitmq.host: rabbitmq的地址。
  • spring.rabbitmq.port: rabbitmq的端口。
  • spring.rabbitmq.username: rabbitmq的用户名。
  • spring.rabbitmq.password: rabbitmq的密码。

:如果是kafka的话,添加kafka的配置信息spring.kafka.bootstrap-servers,填写kafka的地址和端口即可。

服务端代码和之前一样即可,在程序主类中,额外添加@EnableConfigServer注解,该注解表示启用config配置中心功能。代码如下:


    @EnableDiscoveryClient
    @EnableConfigServer
    @SpringBootApplication
    public class ConfigServerApplication {

        public static void main(String[] args) {
            SpringApplication.run(ConfigServerApplication.class, args);
            System.out.println("配置中心服务端启动成功!");
        }
    }

完成上述代码之后,我们的配置中心服务端已经构建完成了。

注册中心和之前保持一致就可以了。

客户端

客户端这边的变动基本不大,增加一个rabbitmq的jar包和相应的配置文件即可。
springcloud-config-bus-clinet的pom文件添加如下配置:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bus-amqp</artifactId>
    </dependency>
</dependencies>

bootstrap.properties文件的配置信息和之前的基本一样,完整的配置如下:

配置信息:

spring.cloud.config.name=configtest
spring.cloud.config.profile=pro
spring.cloud.config.label=master
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=springcloud-config-bus-server
eureka.client.serviceUrl.defaultZone=http://localhost:8006/eureka/

配置说明:

  • spring.cloud.config.name: 获取配置文件的名称。
  • spring.cloud.config.profile: 获取配置的策略。
  • spring.cloud.config.label:获取配置文件的分支,默认是master。如果是是本地获取的话,则无用。
  • spring.cloud.config.discovery.enabled: 开启配置信息发现。
  • spring.cloud.config.discovery.serviceId: 指定配置中心的service-id,便于扩展为高可用配置集群。
  • eureka.client.serviceUrl.defaultZone: 这个是设置与Eureka Server交互的地址,客户端的查询服务和注册服务都需要依赖这个地址。

:上面这些与spring-cloud相关的属性必须配置在bootstrap.properties中,config部分内容才能被正确加载。因为bootstrap.properties的相关配置会先于application.properties,而bootstrap.properties的加载也是先于application.properties。需要注意的是eureka.client.serviceUrl.defaultZone要配置在bootstrap.properties,不然客户端是无法获取配置中心参数的,会启动失败!

application.properties配置文件新增的配置基本和服务端的一样,完整的配置如下:

spring.application.name=springcloud-config-bus-client
server.port=9006
management.endpoints.web.exposure.include=refresh
spring.cloud.config.failFast=true
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

配置说明:

  • spring.application.name: 这个是指定服务名称。
  • server.port:服务指定的端口。
  • management.endpoints.web.exposure.include:暴露刷新的地址。
  • spring.cloud.bus.enabled:是否启用springcloud config bus。
  • spring.cloud.bus.trace.enabled:开启跟踪总线事件。
  • spring.rabbitmq.host: rabbitmq的地址。
  • spring.rabbitmq.port: rabbitmq的端口。
  • spring.rabbitmq.username: rabbitmq的用户名。
  • spring.rabbitmq.password: rabbitmq的密码。

程序主类代码,和之前的基本一致。代码如下:

主程序代码示例:


    @EnableDiscoveryClient
    @SpringBootApplication
    public class ConfigClientApplication {

        public static void main(String[] args) {
            SpringApplication.run(ConfigClientApplication.class, args);
            System.out.println("配置中心客户端启动成功!");
        }
    }

控制层代码:


    @RestController
    @RefreshScope
    public class ClientController {

        @Value("${word}")
        private String word;

        @RequestMapping("/hello")
        public String index(@RequestParam String name) {
            return name+","+this.word;
        }
    }

完成上述的项目开发之后,我们把上面的项目复制一下,项目名称为springcloud-config-bus-client2,然后把它的端口改为9007即可。

到此,客户端的项目也就构建完成了。

功能测试

完成如上的工程开发之后,我们来进行测试。

我们首先启动RabbitMQ服务,然后再依次启动springcloud-config-bus-eurekaspringcloud-config-bus-serverspringcloud-config-bus-clientspringcloud-config-bus-client2这四个项目。其中9005是服务端springcloud-config-bus-server的端口,9006是第一个客户端springcloud-config-bus-client的端口,9007是是第二个客户端springcloud-config-bus-client2的端口。

全局刷新测试

启动成功之后,在浏览器输入:

http://localhost:9006//hello?name=pancm

界面返回:

pancm,hello 

在浏览器输入:

http://localhost:9007//hello?name=xuwujing

界面返回:

xuwujing,hello 

可以正常得到服务端configtest-pro.properties的配置信息。

然后在把configtest-pro.properties的配置更改为:

word=hello!! 

然后在使用Postman工具进行发起POST请求,只不过这次的地址是服务端的地址和端口。

使用POST请求如下地址:

http://localhost:9005/actuator/bus-refresh

然后我们再浏览器输入:

http://localhost:9006//hello?name=pancm

界面返回:

pancm,hello!! 

浏览器输入:

http://localhost:9007//hello?name=pancm

界面返回:

xuwujing,hello!! 

示例图:




局部刷新测试

完成上述全局刷新测试之后,有时我们只想刷新部分微服务的配置,那么便可以使用/actuator/bus-refresh/{destination}端点的 destination 参数来定位要刷新的应用程序。

我们继续更改configtest-pro.properties的配置为:

word=hello!!!

然后依旧使用Postman工具发送post请求,地址为:

http://localhost:9005/actuator/bus-refresh/springcloud-config-bus-client2

然后我们再浏览器输入:

http://localhost:9006//hello?name=pancm

界面返回:

pancm,hello!! 

浏览器输入:

http://localhost:9007//hello?name=pancm

界面返回:

xuwujing,hello!!! 

发现只有springcloud-config-bus-client2客户端的配置更新,另一个springcloud-config-bus-client没有进行刷新,达到了我们的目的。

示例图:


上述示例完成之后,我们把SpringCloud Config Refresh的测试在进行一遍,发现依旧可以实现,因此我们发现只要开启Spring Cloud Bus 后,不管是对服务端还是客户端,执行/actuator/bus-refresh都是可以更新配置的。

如果我们想进行跟踪总线事件的话,只需要在刷新配置之后,在地址后面添加/trace/actuator/httptrace即可。

其他

项目地址

基于SpringBoot2.x、SpringCloud的Finchley版本开发的地址:https://github.com/xuwujing/springcloud-study

如果感觉项目不错,希望能给个star,谢谢!

音乐推荐

原创不易,如果感觉不错,希望留言推荐!您的支持是我写作的最大动力!
版权声明:
作者:虚无境
博客园出处:http://www.cnblogs.com/xuwujing
CSDN出处:http://blog.csdn.net/qazwsxpcm    
个人博客出处:http://www.panchengming.com

原文地址:https://www.cnblogs.com/xuwujing/p/10602687.html

时间: 2024-10-11 03:40:20

SpringCloud学习系列之五-----配置中心(Config)和消息总线(Bus)完美使用版的相关文章

SpringCloud学习系列之七 ----- Zuul路由网关的过滤器和异常处理

前言 在上篇中介绍了SpringCloud Zuul路由网关的基本使用版本,本篇则介绍基于SpringCloud(基于SpringBoot2.x,.SpringCloud Finchley版)中的路由网关的过滤器Filter以及异常处理的教程. SpringCloud Zuul Filter 介绍 过滤器概述 Zuul的中心是一系列过滤器,能够在HTTP请求和响应的路由过程中执行一系列操作. 以下是Zuul过滤器的主要特征: 类型:通常在应用过滤器时在路由流程中定义阶段(尽管它可以是任何自定义字

eShopOnContainers学习系列(三):RabbitMQ消息总线实践

今天研究了下eShopOnContainers里的RabbitMQ的使用,在项目里是以封装成消息总线的方式使用的,但是仍然是以其发布.订阅两个方法作为基础封装的,我们今天就来实际使用一下. 为了简单起见,就在同一个API项目里实现发布订阅. 新建API项目 RabbitMQ_Bus_Test ,类库 EventBus.EventBusRabbitMQ,这两个类库中将会实现消息总线最主要的方法.发布订阅. 在EventBus中新增消息事件类:IntegrationEvent,这个类在事件里是作为一

springcloud应用配置中心config的安全设置

springcloud应用配置中心config的安全设置 在springcloud应用开发中,为了方便在线管理我们的配置文件,通常会配一个配置中心config-server,这里托管着应用的一些配置文件,这些配置文件中配置着我们很多的账号信息:如mysql.redis.mongodb.rabbitmq等等的账号和密码.牵扯到账号信息,想必我们要保证如何保证其安全性. 1.保证容器文件访问的安全性,即保证所有的网络资源请求都需要登录 通过springboot配置属性之security,配置secu

SpringCloud之配置中心Config

commons 工程commons 工程 - POM 文件<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://mav

SpringCloud学习系列之三----- 断路器Hystrix和断路器监控Dashboar

前言 本篇主要介绍的是SpringCloud中的断路器(Hystrix)和断路器指标看板(Dashboard)的相关使用知识. SpringCloud Hystrix Hystrix 介绍 Netflix创建了一个名为Hystrix的库,它实现了断路器模式.主要的目的是为了解决服务雪崩效应的一个组件,是保护服务高可用的最后一道防线. 开发准备 开发环境 JDK:1.8 SpringBoot:2.1.1.RELEASE SpringCloud:Finchley 注:不一定非要用上述的版本,可以根据

10、服务提供者provider如何使用配置中心config

前面的<配置中心>和<服务注册&服务提供者>这两篇分别讲解了配置中心和服务提供者,但是服务提供者使用的配置文件还是本地的,没有使用配置中心的配置文件.今天看看如何实现服务提供者使用配置中心的配置文件. 1. 新建项目sc-eureka-client-provider-config,项目对应的pom.xml文件如下 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="h

WPF学习系列之五(WPF控件)

控件:    1.内容控件------这些控件能够包含嵌套的元素,为它们提供几乎无限的显示能力.内容控件包括Lable,Button 以及ToolTip类. 内容控件是更特殊的控件类型,它们可以包含(并显示)一块内容.从技术角度来讲,内容控件是可以包含单个嵌套元素的控件.与布局容器不同的是内容控件只能包含一个子元素,而布局控件只要愿意可以包含任意多个嵌套元素.              提示:当然,仍然可以在单个内容控件中放置大量内容-----诀窍是使用单个容器,比如,使用StackPanel面

Spring Cloud(九):配置中心(消息总线)【Finchley 版】

Spring Cloud(九):配置中心(消息总线)[Finchley 版] 发表于 2018-04-19 |  更新于 2018-05-07 | 我们在 Spring Cloud(七):配置中心(Git.Refresh) 中讲到,如果需要客户端获取到最新的配置信息需要执行refresh,我们可以利用 Webhook 的机制每次提交代码发送请求来刷新客户端,当客户端越来越多的时候,需要每个客户端都执行一遍,这种方案就不太适合了.使用 Spring Cloud Bus 可以完美解决这一问题. Sp

Android学习系列(7)--App轮询服务器消息

这篇文章是android开发人员的必备知识. 1.轮询服务器     一般的应用,定时通知消息可以采用轮询的方法从服务器拿取消息,当然实时消息通知的话,建议采用推送服务.    其中需要注意轮询的频率设置,要在需求和性能中平衡. 2.独立进程     无论程序是否正在运行,我们都要能通知到客户,我们需要一个独立进程的后台服务.     我们需要一个独立进程的后台服务.     在AndroidManifest.xml中注册Service时,有一个android:process属性,如果这个属性以