SpringCloud-2.0-周阳(14. 消息总线 - SpringCloud Bus)
Posted ABin-阿斌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud-2.0-周阳(14. 消息总线 - SpringCloud Bus)相关的知识,希望对你有一定的参考价值。
上一篇 :13. 分布式配置中心 - SpringCloud Config
下一篇 :15. 消息驱动 - SpringCloud Stream
- 声明:原文作者:csdn:yuan_404
文章目录
文章目录
1 . 概述
- 上一篇的最后实现了,不需要重启服务器就可以实现 Config-Client 信息的更新,但是依旧是手动的,当服务多了之后,很不方便。
- 所以引出了 SpringCloud Bus
- Spring Cloud Bus 配合 Spring Cloud Config 使用可以实现配置的动态刷新
1.1 简介
-
Bus 是支持 SpringCloud 的一种 消息总线
-
Bus 只支持两种消息代理:RabbitMQ 和 Kafka
-
Spring Cloud Bus 是用来将分布式系统的节点与轻量级消息系统链接起来的框架
-
它整合了Java的事件处理机制和消息中间件的功能。
1.2 作用
- Spring Cloud Bus 能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更改、事件推送等,也可以当作微服务间的通信通道。
1.3 总线
- 什么是总线
在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题(类似关注公众号),并让系统中所有微服务实例都连接上来。由于该主题中产生的消息会被所有实例监听和消费,所以称它为消息总线。在总线上的各个实例,都可以方便地广播─些需要让其他连接在该主题上的实例都知道的消息。
- 基本原理
ConfigClient 实例都监听 MQ 中同一个 topic (默认是springCloudBus)。当一个服务刷新数据的时候,它会把这个信息放入到Topic中,这样其它监听同一 Topic 的服务就能得到通知,然后去更新自身的配置。
2 . RabbitMQ 环境配置
- 安装Erlang
- 安装RabbitMQ
-
CMD 进入 RabbitMQ 安装目录下的sbin目录
-
添加可视化插件
输入以下命令启动管理功能
rabbitmq-plugins enable rabbitmq_management
- 注意
在执行这一步的时候要确保安装的电脑的名称中不能出现中文,不然会报错
-
启动 RabbitMQ 服务
还在上面的 CMD 界面中输入 :
rabbitmqctl start_app
-
访问地址查看是否安装成功
http://localhost:15672/
- 注意
如果完成了 4、5 两步,但是无法访问该网址,那么可以尝试 —— RabbitMQ 安装并成功启动后,无法访问 http://localhost:15672/
- 登录:
账号 :guest
密码 :guest
3 . SpringCloud Bus动态刷新全局广播
3.1 添加一个 Config-Client
-
新建模块 :cloud-config-client-3366
演示广播效果,增加复杂度,再以3355为模板再制作一个3366
-
修改 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-client</artifactId> </dependency> <dependency> <groupId>com.demo.springcloud</groupId> <artifactId>cloud-api-commons</artifactId> <version>$project.version</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
-
编写 YML :bootstrap.yml
server: port: 3366 spring: application: name: config-client cloud: config: # 分支名称 label: master # 配置文件名 name: config # 环境 profile: dev # 配置中心的地址 uri: http://localhost:3344 eureka: client: service-url: defaultZone: http://localhost:7001/eureka management: endpoints: web: exposure: include: "*"
-
编写主启动类
@EnableEurekaClient @SpringBootApplication public class ConfigClientMain3366 public static void main(String[] args) SpringApplication.run( ConfigClientMain3366.class,args);
-
业务类
-
Controller
@RestController @RefreshScope public class ConfigClientController @Value("$server.port") private String serverPort; @Value("$config.info") private String configInfo; @GetMapping("/configInfo") public String getConfigInfo() return "serverPort:"+serverPort+"\\t\\n\\n configInfo: "+configInfo;
3.2 设计方案
-
方案1 :利用消息总线触发一个 客户端 /bus/refresh ,而刷新所有客户端的配置
-
方案2 :利用消息总线触发一个 服务端 ConfigServer 的 /bus/refresh 端点,而刷新所有客户端的配置(更加推荐)
-
方案2 的架构显然更加合适,方案1 不适合的原因如下
- 打破了微服务的职责单一性,因为微服务本身是业务模块,它本不应该承担配置刷新职责
- 破坏了微服务各节点的对等性
- 有一定的局限性。例如,微服务在迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新,那就会增加更多的修改
3.3 添加消息总线支持
- 修改 Config-Center-3344
-
修改 POM
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
-
修改 YML
# RabbitMQ 相关配置 rabbitmq: host: localhost port: 5672 username: guest password: guest
management: # 暴露 Bus 刷新配置的端点 endpoints: web: exposure: include: 'bus-refresh'
- 修改 Config-Client-3355、3366
-
修改 POM
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
-
修改 YML
# RabbitMQ 相关的配置 rabbitmq: host: localhost port: 5672 username: guest password: guest
-
启动项目
3.4 测试
-
修改Github上配置文件增加版本号
-
先读取一下配置中心、及客户端的配置信息
http://localhost:3344/config-dev.yml http://localhost:3355/configInfo http://localhost:3366/configInfo
-
打开 CMD 发送 POST 请求
curl -X POST "http://localhost:3344/actuator/bus-refresh"
- 这个请求最后的 bus-refresh 也就是在 Config-Center-3344 中配置的被打开的端口
-
两个客户端读取信息
http://localhost:3355/configInfo http://localhost:3366/configInfo
-
结果 :一次修改、广播通知、处处生效
4 . SpringCloud Bus动态刷新定点通知
-
上面配置的是广播,通知了所有的客户端,但是现在不想通知全部,想要实现定点通知
-
定点刷新的请求样式
http://localhost:配置中心的端口号/actuator/bus-refresh/destination
/bus-refresh 请求不再发送到具体的服务实例上,而是发给 config server 并通过 destination 参数类指定需要更新配置的服务或实例
-
示例:只通知3355,不通知3366
-
修改 GIT 上的配置文件
-
发出定点刷新的请求
curl -X POST "http://localhost:3344/actuator/bus-refresh/config-client:3355"
-
查看 Config-Client-3355
http://localhost:3355/configInfo
-
查看 Config-Client-3366
http://localhost:3366/configInfo
5 . 总结
以上是关于SpringCloud-2.0-周阳(14. 消息总线 - SpringCloud Bus)的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloud-2.0-周阳(13. 分布式配置中心 - SpringCloud Config)
SpringCloud-2.0-周阳(16. 请求链路追踪 - SpringCloud Sleuth)
SpringCloud-2.0-周阳(17. SpringCloud Alibaba入门简介)
SpringCloud-2.0-周阳(21. Sentinel 环境搭建)