1. 消息总线概述

1.1 分布式配置的动态刷新问题
  • Linux运维修改Github上的配置文件内容做调整
  • 刷新3344,发现ConfigServer配置中心立刻响应
  • 刷新3355,发现ConfigClient客户端没有任何响应
  • 3355没有变化除非自己重启或者重新加载
  • 难道每次运维修改配置文件,客户端都需要重启?
1.2 消息总线加强Config

SpringCloud Bus配合SpringCloud Config使用可以实现配置的动态刷新。

用SpringCloud Config时,我们可以实现配置信息手动的动态刷新,也就是远端配置信息发生改变后,需要告诉服务端配置信息发生变化后,服务端才会更新配置信息,而现在我们想要实现分布式自动刷新配置信息功能,这就需要我们使用SpringCloud Bus消息总线配合SpringCloud Config实现配置信息的动态刷新。

SpringCloud Bus是用来将分布式系统的节点与轻量级消息系统连接起来的框架,它整合了Java的事件处理机制和消息中间件的功能,SpringCloud Bus目前支持两种消息代理:RabbitMQ和Kafka。

SpringCloud Bus能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更改、事件推送等, 也可以当做微服务间的通信通道。

1.2 为什么被称为总线

在微服务架构的系统中,通常会 使用轻量级的消息代理 来构建一个 共用的消息主题,并让系统中所有微服务实例都连接上来,由于 该主题中产生的消息会被所有实例监听和消费,所以称它为消息总线。在总线上的各个实例,都可以方便地广播一些需要让其他连接在该主题上的实例都知道的消息。

基本原理:SpringCloud Config客户端的实例都监听消息队列中的同一个主题(topic)(默认是SpringCloud Bus),当一个服务器刷新数据的时候,它会把这个信息放入到主题中,这样其他监听了同一主题的服务就能得到通知,然后去更新自身的配置。

1.3 安装RabbitMQ

直接使用docker-compose安装吧!

访问地址看是否安装成功:http://localhost:15672,输入账号并登录,默认guest/guest

2. SpringCloud Bus动态刷新全局广播

在学习SpringCloud Config的时候我们已经建立了服务cloud-config-client-3355作为Config的客户端,这里为了演示广播效果,我们增加复杂度,再以3355为模板再制作另一个Config的客户端3366,建立Module:cloud-config-client-3366,其结构和cloud-config-client-3355类似,修改下服务端口号即可。

修改以下3355/3366的controller,用于区分

@RestController
@RefreshScope
public class ConfigClientController {
@Value("${server.port}")
private String serverPort; @Value("${server.info}")
private String configInfo; @GetMapping("/configInfo")
public String getConfigInfo() {
return "serverPort:" + serverPort + "\t configInfo:" + configInfo;
}
}
2.1 消息总线的两种设计思想

方案一

利用消息总线 触发一个客户端/bus/refresh端点,而后刷新所有客户端的配置:

方案二

利用消息总线 触发一个服务端ConfigServer的/bus/refresh端点,而后刷新所有客户端的配置:

两种方案对比

明显第二种架构更加合适,第一种架构不合适的原因主要有:

  • 打破了微服务的职责单一性,因为微服务本身是业务模块,它本不应该承担配置刷新的职责

  • 破坏了微服务各节点的对等性

  • 有一定的局限性,比如在微服务迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新,那就会增加更多的修改

所以虽然从技术上两种方案都可以实现,但是无疑在技术选型上我们应该选择第二种方案。

2.2 3344服务端添加消息总线支持

在其POM文件中添加使用RabbitMQ实现消息总线的依赖:

<!--添加消息总线RabbitMQ支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

然后在其yml配置文件中添加RabbitMQ的相关配置,暴露SpringCloud Bus刷新配置的端点

# RabbitMQ相关配置
spring:
rabbitmq:
host: mpolaris.top
port: 5672
username: admin
password: 1234321
# 暴露总线刷新配置的端点
management:
endpoints:
web:
exposure:
include: 'bus-refresh'
2.3 3355/3366客户端添加消息总线支持

在其POM文件中添加RabbitMQ实现总线的依赖(同ConfigServer的相关依赖):

<!--添加消息总线RabbitMQ支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

然后在其yml配置文件中添加RabbitMQ的相关配置:

# RabbitMQ相关配置
spring:
rabbitmq:
host: mpolaris.top
port: 5672
username: admin
password: 1234321
2.4 测试

按顺序启动Eureka服务注册中心7001,ConfigServer配置中心3344,ConfigClient配置中心客户端3355/3366,此时远端GitHub上的配置信息如下:

server:
info: my name is config server , this is master/config-dev.yml

分别访问配置中心及其配置中心客户端的服务中心,发现结果都是一样的。

然后将Gitee远端的配置信息中info加一个 =>,然后对服务配置中心发送POST请求:

curl -X POST "{配置中心的地址}/actuator/bus-refresh"

# 如此时我们该发送的POST请求为:
curl -X POST "http://localhost:3344/actuator/bus-refresh"

此时再访问配置中心及客户端的配置信息,发现所有服务的配置信息都得到了更新:

打开RabbitMQ的控制面板,我们可以发现有一个交换机,这就对应消息总线发送消息的交换机:

3. SpringCloud Bus动态刷新定点通知

在全局广播中,我们更新配置文件的信息对所有服务都进行了通知,但是假设我们只想通知3355,而不想通知3366又该怎么办呢,这就需要我们用定点通知的方法通知3355,也就是说我们进行消息通知时只指定具体某个实例生效而不是全部生效,这种情况下就需要修改我们发送的POST请求:

curl -X POST "http://{配置中心的地址}/actuator/bus-refresh/{destination}"

这样的话,actuator/bus-refresh请求就不再发送到具体的服务实例上,而是发给ConfigServer配置中心并通过destination参数指定需要更新配置的服务或实例。其中destination具体为 微服务+端口号。

比如现在我们修改远端配置文件,但是我们只想通知3355的配置更新信息,而不想通知3366,此时我们发送的POST请求就应该是:

curl -X POST "http://localhost:3344/actuator/bus-refresh/config-client:3355"

八. SpringCloud消息总线的更多相关文章

  1. 【SpringCloud 】第八篇: 消息总线(Spring Cloud Bus)

    前言: 必需学会SpringBoot基础知识 简介: spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选. ...

  2. 原 史上最简单的SpringCloud教程 | 第八篇: 消息总线(Spring Cloud Bus)(Finchley版本)

    转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springcloud/2018/08/30/sc-f8-bus/ 本文出自方志朋的博客 转载请标明出处: Spr ...

  3. 史上最简单的SpringCloud教程 | 第八篇: 消息总线(Spring Cloud Bus)

    转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springcloud/2017/07/12/sc08-bus/ 本文出自方志朋的博客 最新Finchley版本请 ...

  4. SpringCloud学习(八)消息总线(Spring Cloud Bus)(Finchley版本)

    Spring Cloud Bus 将分布式的节点用轻量的消息代理连接起来.它可以用于广播配置文件的更改或者服务之间的通讯,也可以用于监控.本文要讲述的是用Spring Cloud Bus实现通知微服务 ...

  5. SpringCloud消息总线

    我们在springcloud(七):配置中心svn示例和refresh中讲到,如果需要客户端获取到最新的配置信息需要执行refresh,我们可以利用webhook的机制每次提交代码发送请求来刷新客户端 ...

  6. SpringCloud教程 | 第八篇: 消息总线(Spring Cloud Bus)

    一.安装rabbitmq 二.pom父文件 <?xml version="1.0" encoding="UTF-8"?> <project x ...

  7. SpringCloud之Config配置中心+BUS消息总线原理及其配置

    一.配置中心作用 在常规的开发中,每个微服务都包含代码和配置.其配置包含服务配置.各类开关和业务配置.如果系统结构中的微服务节点较少,那么常规的代码+配置的开发方式足以解决问题.当系统逐步迭代,其微服 ...

  8. 跟我学SpringCloud | 第八篇:Spring Cloud Bus 消息总线

    SpringCloud系列教程 | 第八篇:Spring Cloud Bus 消息总线 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如无特 ...

  9. SpringCloud(八):springcloud-bus消息总线(刷新配置服务)

    Bus消息总线: 好了现在我们接着上一篇的随笔,继续来讲.上一篇我们讲到,我们如果要去更新所有微服务的配置,在不重启的情况下去更新配置,只能依靠spring cloud config了,但是,是我们要 ...

随机推荐

  1. Codeforces Round #570 (Div. 3) B. Equalize Prices、C. Computer Game、D. Candy Box (easy version)、E. Subsequences (easy version)

    B题题意: 给你n个物品的价格,你需要找出来一个值b,使得每一个物品与这个b的差值的绝对值小于k.找到最大的b输出,如果找不到,那就输出-1 题解: 很简单嘛,找到上下限直接二分.下限就是所有物品中最 ...

  2. fzu2204 7

    Problem Description n个有标号的球围成一个圈.每个球有两种颜色可以选择黑或白染色.问有多少种方案使得没有出现连续白球7个或连续黑球7个.  Input 第一行有多组数据.第一行T表 ...

  3. python代理池的构建1——代理IP类的构建,以及配置文件、日志文件、requests请求头

    一.整体结构 二.代理IP类的构建(domain.py文件) ''' 实现_ init_ 方法, 负责初始化,包含如下字段: ip: 代理的IP地址 port:代理IP的端口号 protocol: 代 ...

  4. 牛客编程巅峰赛S1第11场 - 黄金&钻石 B.新集合 (DFS)

    题意:有\([1,n]\)这\(n\)个数,构造集合,集合中不能包含\(u\)和\(v\),问最多能构造多少个集合. 题解:被这题卡了一整场.....以为是推公式,结果答案是暴搜? ​ 首先我们先用一 ...

  5. P站风格的DevTools主题

    Chrome插件地址:https://chrome.google.com/webstore/detail/material-devtools-theme-c/jmefikbdhgocdjeejjnne ...

  6. WPF Animation For SizeChanged Of UIElement

    效果图 学到一个新词: Show me the money 背景 这几天查资料,看到 CodeProject 上面的一篇 Post <Advanced Custom TreeView Layou ...

  7. JDK的卸载与安装

    JDK的卸载 删除Java的安装目录 删除JAVA_HOME 删除path下关于Java的目录 DOS命令Java -version查看状态 JDK的安装 百度搜索jdk8,找到下载地址 同意协议 下 ...

  8. LaTex公式在线转图片

    Reference https://latex.codecogs.com/gif.latex?THE_FORMULAR 注: 请不要包含空格 或者 将整段url放到浏览器里, 会产生空格等字符的替换, ...

  9. JavaScript 注释规范

    JavaScript 注释规范 总原则 As short as possible(如无必要,勿增注释).尽量提高代码本身的清晰性.可读性. As long as necessary(如有必要,尽量详尽 ...

  10. input composition event All In One

    input composition event All In One input event compositionStart & compositionEnd & compositi ...