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 292E. Copying Data

    We often have to copy large volumes of information. Such operation can take up many computer resourc ...

  2. Codeforces Round #479 (Div. 3) C. Less or Equal (排序,贪心)

    题意:有一个长度为\(n\)的序列,要求在\([1,10^9]\)中找一个\(x\),使得序列中恰好\(k\)个数满足\(\le x\).如果找不到\(x\),输出\(-1\). 题解:先对这个序列排 ...

  3. 【非原创】ZOJ - 4062 Plants vs. Zombies【二分】

    题目:戳这里 题意:机器人走过一个花,可以给那个花浇水,给定步数下,问花的最小的最大能量值. 学习博客:戳这里 本人代码: 1 #include <bits/stdc++.h> 2 typ ...

  4. spyder import tensorflow

    之前安装了tensorflowgpu,但是在spyder中import会失败. 原因是因为新建了环境,要activate tensorflow-gpu进入安装了tensorflow 的环境才可以imp ...

  5. bzoj4355 Play with sequence(吉司机线段树)题解

    题意: 已知\(n\)个数字,进行以下操作: \(1.\)区间\([L,R]\) 赋值为\(x\) \(2.\)区间\([L,R]\) 赋值为\(max(a[i] + x, 0)\) \(3.\)区间 ...

  6. HDU4578 Transformation(多标记线段树)题解

    题意: 操作有:\(1\).区间都加\(a\):\(2\).区间都乘\(a\):\(3\).区间都重置成\(a\):\(4\).询问区间幂次和\(\sum_{i=l}^rnum[i]^p(p\in\{ ...

  7. css background transparent All In One

    css background transparent All In One opacity ul { max-height: 100px; /* max-height: 187px; */ overf ...

  8. CSS 水平滚动条 bug & width auto increase bug

    CSS 水平滚动条 bug css overflow & width auto increase bug 问题排查方式 删除可疑的模块,一步步找到问题的原因,定位问题所在 寻找可能会导致 wi ...

  9. TypeScript TSConfig All In One

    TypeScript TSConfig All In One tsconfig.json https://www.typescriptlang.org/tsconfig https://www.typ ...

  10. js 深入原理讲解系列-currying function

    js 深入原理讲解系列-currying function 能看懂这一题你就掌握了 js 科里函数的核心原理 不要专业的术语,说人话,讲明白! Q: 实现 sum 函数使得以下表达式的值正确 cons ...