八. SpringCloud消息总线
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消息总线的更多相关文章
- 【SpringCloud 】第八篇: 消息总线(Spring Cloud Bus)
前言: 必需学会SpringBoot基础知识 简介: spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选. ...
- 原 史上最简单的SpringCloud教程 | 第八篇: 消息总线(Spring Cloud Bus)(Finchley版本)
转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springcloud/2018/08/30/sc-f8-bus/ 本文出自方志朋的博客 转载请标明出处: Spr ...
- 史上最简单的SpringCloud教程 | 第八篇: 消息总线(Spring Cloud Bus)
转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springcloud/2017/07/12/sc08-bus/ 本文出自方志朋的博客 最新Finchley版本请 ...
- SpringCloud学习(八)消息总线(Spring Cloud Bus)(Finchley版本)
Spring Cloud Bus 将分布式的节点用轻量的消息代理连接起来.它可以用于广播配置文件的更改或者服务之间的通讯,也可以用于监控.本文要讲述的是用Spring Cloud Bus实现通知微服务 ...
- SpringCloud消息总线
我们在springcloud(七):配置中心svn示例和refresh中讲到,如果需要客户端获取到最新的配置信息需要执行refresh,我们可以利用webhook的机制每次提交代码发送请求来刷新客户端 ...
- SpringCloud教程 | 第八篇: 消息总线(Spring Cloud Bus)
一.安装rabbitmq 二.pom父文件 <?xml version="1.0" encoding="UTF-8"?> <project x ...
- SpringCloud之Config配置中心+BUS消息总线原理及其配置
一.配置中心作用 在常规的开发中,每个微服务都包含代码和配置.其配置包含服务配置.各类开关和业务配置.如果系统结构中的微服务节点较少,那么常规的代码+配置的开发方式足以解决问题.当系统逐步迭代,其微服 ...
- 跟我学SpringCloud | 第八篇:Spring Cloud Bus 消息总线
SpringCloud系列教程 | 第八篇:Spring Cloud Bus 消息总线 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如无特 ...
- SpringCloud(八):springcloud-bus消息总线(刷新配置服务)
Bus消息总线: 好了现在我们接着上一篇的随笔,继续来讲.上一篇我们讲到,我们如果要去更新所有微服务的配置,在不重启的情况下去更新配置,只能依靠spring cloud config了,但是,是我们要 ...
随机推荐
- zoj3777 Problem Arrangement(状压dp,思路赞)
The 11th Zhejiang Provincial Collegiate Programming Contest is coming! As a problem setter, Edward i ...
- C# 静态类 单例模式 对比
公司的类都需要使用单例模式实现,这个可以节省资源,避免重复对象的生成.但是静态类也可以做到这一点,而且写起来更简洁,于是查阅相关资料,希望弄明白两者的差别. 1.单例模式可以在用到的时候初始化,而静态 ...
- Leetcode(871)-最低加油次数
汽车从起点出发驶向目的地,该目的地位于出发位置东面 target 英里处. 沿途有加油站,每个 station[i] 代表一个加油站,它位于出发位置东面 station[i][0] 英里处,并且有 s ...
- C、C++语言中参数的压栈顺序
要回答这个问题,就不得不谈一谈printf()函数,printf函数的原型是:printf(const char* format,-) 没错,它是一个不定参函数,那么我们在实际使用中是怎么样知道它的参 ...
- LWIP再探----内存堆管理
LWIP的内存管理主要三种:内存池Pool,内存堆,和C库方式.三种方式中C库因为是直接从系统堆中分配内存空间且易产生碎片因此,基本不会使用,其他两种是LWIP默认全部采用的方式,也是综合效率和空间的 ...
- GUI编程
组件 窗口 弹窗 面板 文本框 列表框 按钮 图片 监听事件 鼠标 键盘事 破解工具 简介 GUI的核心技术:Swing AWT 界面不美观 需要jre环境 为了了解MVC架构 了解监听. AWT 包 ...
- tfrecords转图片存储
import os import shutil import tensorflow as tf import time import sys import cv2 # 图片存放位置 PATH_RES ...
- css position sticky All In One
css position sticky All In One css sticky & 吸顶效果 demo https://codepen.io/xgqfrms/pen/PoqyVYz ref ...
- HTML5 动画效果的多种实现方式
HTML5 动画效果的多种实现方式 1. CSS3 transform + transition https://www.w3.org/TR/css-transforms-1/ https://ww ...
- 微信小程序-云开发实战教程
微信小程序-云开发实战教程 云函数,云存储,云数据库,云调用 https://developers.weixin.qq.com/miniprogram/dev/wxcloud/basis/gettin ...