11.7 Config+Bus 实现配置的动态刷新
-
从前面的例子中,我们通过在 Config 客户端(端口号:8017)中引入 Spring Boot actuator 监控组件来监控配置的变化,使我们可以在不重启 Config 客户端的情况下获取到了最新配置,原理如下图。
-
这虽然解决了重启 Config Client才能获取最新配置的问题,但对于微服务系统而言只要配置仓库中的配置发生改变,就需要我们逐个向 Config 客户端手动发送 POST 请求,通知它们重新拉取配置,这种运维就太吃力了。
-
利用Spring Cloud Config + Bus可以实现配置的动态刷新,做到一次通知,各处刷新
-
Spring Cloud Bus 又被称为消息总线,它能够通过轻量级的消息代理(例如 RabbitMQ、Kafka 等)将微服务架构中的各个服务连接起来,实现广播状态更改、事件推送等功能,还可以实现微服务之间的通信功能。
-
Spring Cloud Bus 的基本原理:Spring Cloud Bus 会使用一个轻量级的消息代理来构建一个公共的消息主题 Topic(默认为“springCloudBus”),这个 Topic 中的消息会被所有服务实例监听和消费。当其中的一个服务刷新数据时,Spring Cloud Bus 会把信息保存到 Topic 中,这样监听这个 Topic 的服务就收到消息并自动消费。
-
利用 Spring Cloud Bus 的特殊机制可以实现很多功能,其中配合 Spring Cloud Config 实现配置的动态刷新就是最典型的应用场景之一。
-
Spring Cloud Bus 动态刷新配置的原理:当 Git 仓库中的配置发生了改变,我们只需要向某一个服务(可以是 Config 服务端,也可以是 Config 客户端)发送一个 POST 请求,Spring Cloud Bus 就可以通过消息代理通知其他服务重新拉取最新配置,以实现配置的动态刷新。原理如下图:
-
Spring Cloud Bus 实现配置的动态刷新需要以下步骤:
- 当 Git 仓库中的配置发生改变后,运维人员向 Config 服务端发送一个 POST 请求,请求路径为“/actuator/refresh”。
- Config 服务端接收到请求后,会将该请求转发给服务总线 Spring Cloud Bus。
- Spring Cloud Bus 接到消息后,生成 Topic然后会通知给所有 Config 客户端。
- Config 客户端接收到通知,请求 Config 服务端拉取最新配置。
- 所有 Config 客户端都获取到最新的配置。
- 下面采用RabbitMQ消息队列,测试下利用
11.7.1 Spring Cloud Bus 动态刷新配置(全局广播)
- 下面采用RabbitMQ消息队列,实现 Spring Cloud Bus 动态刷新配置(全局广播)
- 在使用 Spring Cloud Bus 时,要确定 Bus 所连接的消息代理软件RabbitMQ消息队列已经安装且正常运行,请翻阅博客消息中间件-RabbitMq安装步骤
- 动态刷新配置要使用 Spring Boot actuator 监控模块和 Spring Cloud Bus 的依赖。所以在配置中心服务microservice-cloud-config-server-8016的 pom.xml 中配置,由于已经添加了添加Spring Boot actuator 监控模块,只需补充倒入bus依赖。代码如下
<!--添加消息总线(Bus)对 RabbitMQ 的支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
- 在 microservice-cloud-config-server-8016 的配置文件 application.yml 中,添加 RabbitMQ 和 Spring Boot actuator 的相关配置,配置内容如下。
spring:
rabbitmq: # RabbitMQ 相关配置,15672 是web 管理界面的端口,5672 是 MQ 的访问端口
host: localhost
username: guest
password: guest
port: 5672
# Spring Boot 2.50对 actuator 监控屏蔽了大多数的节点,只暴露了 heath 节点,本段配置(*)就是为了开启所有的节点
management:
endpoints:
web:
exposure:
include: health,info,hystrix.stream,bus-refresh #应包含的端点 ID 或 '' 全部,* 在yaml 文件属于关键字,所以需要加双引号
#include的值也可以改成*,但建议还是最小暴露原则,用啥开启啥
- 在microservice-cloud-config-client-8017 的 pom.xml 中,添加 Spring Cloud Bus 的相关依赖,代码如下。
<!--添加消息总线(Bus)对 RabbitMQ 的支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
- 在 microservice-cloud-config-client-8017 的配置文件 bootstrap.yml 中添加以下配置。
spring:
rabbitmq: # RabbitMQ 相关配置,15672 是web 管理界面的端口,5672 是 MQ 的访问端口
host: localhost
username: guest
password: guest
port: 5672
- 参照 microservice-cloud-config-client-8017,新建一个名为microservice-cloud-config-client-8018 的maven 模块(端口号为 8017)
- 在microservice-cloud-config-client-8018的配置文件 bootstrap.yml 中添加以下配置。
#bootstrap.yml 是系统级别的,加载优先级高于 application.yml ,负责从外部加载application.yml配置并解析
server:
port: 8018
spring:
application:
name: microServiceCloudConfigClientBus #微服务名称,对外暴漏的微服务名称,十分重要
cloud:
config:
label: master #仓库分支名
name: application #配置文件名称,如:application-dev.yml 中的 application,或application.yml集成配置文件
profile: dev #环境名 如:application-dev.yml 中的 application, 中的 dev,或application.yml继承环境中的dev
#别忘记添加 http:// 否则无法读取
##Spring Cloud Config Server地址
uri: http://localhost:8016
rabbitmq: # RabbitMQ 相关配置,15672 是web 管理界面的端口,5672 是 MQ 的访问端口
host: localhost
username: guest
password: guest
port: 5672
#eureka配置,Spring cloud 自定义服务名称和 ip 地址
eureka:
client:
fetch-registry: true
service-url:
#defaultZone: http://localhost:7001/eureka/ #这个地址是 7001注册中心在 application.yml 中暴露出来额注册地址 (单机版)
defaultZone: http://eurekaserver7001.com:7001/eureka/,http://eurekaserver7002.com:7002/eureka/,http://eurekaserver7003.com:7003/eureka/ #将服务注册到 Eureka Server 集群
instance:
instance-id: microservice-cloud-config-server-8018 #自定义服务名称描述信息
prefer-ip-address: true #显示访问路径的 ip 地址
#zookeeper需要配置那些服务service被扫描,eureka则是将整个服务包注册进去了
ribbon:
eager-load:
enabled: true #关闭懒加载
# 指的是建立连接后从服务器读取到可用资源所用的时间
ReadTimeout: 6000
# 指的是建立连接所用的时间,适用于网络状态正常的情况下,两端连接所用的时间
ConnectTimeout: 6000
MaxAutoRetriesNextServer: 1
MaxAutoRetries: 1
# spring cloud 使用 Spring Boot actuator 监控完善信息
# Spring Boot 2.50对 actuator 监控屏蔽了大多数的节点,只暴露了 heath 节点,本段配置(*)就是为了开启所有的节点
management:
endpoints:
web:
exposure:
include: "*" #应包含的端点 ID 或 '' 全部,* 在yaml 文件属于关键字,所以需要加双引号
#include的值也可以改成*,但建议还是最小暴露原则,用啥开启啥health,info,hystrix:stream
info:
env:
enabled: true #启用配置里的info开头的变量
info: #配置一些服务描述信息,监控信息页面显示,,可以判断服务是否正常
app.name: microservice-cloud-config-server-8018
company.name: cloud.zk.com
auth: zk
email: 123@qq.com
build.aetifactId: @project.artifactId@
build.version: @project.version@
# zuul中包含actuator依赖
-
依次重启 microservice-cloud-config-server-8016、microservice-cloud-config-client-8017、microservice-cloud-config-client-8018,使用浏览器访问“http://localhost:8017/getInfo”,结果如下图。
-
使用浏览器访问“http://localhost:8018/getInfo”,结果如下图。
-
将配置文件 config-dev.yml 中的 config.version 修改为 4.0,配置如下。
-
将本地仓库的application.yml文件修改下信息,在提交到仓库上去
-
打开命令行窗口,使用以下命令向 microservice-cloud-config-server-8016(Config Server)发送一个 POST 请求,刷新配置。
curl -X POST "http://localhost:8016/actuator/busrefresh"
- 使用浏览器访问“http://localhost:8017/getInfo”,结果如下图。
- 使用浏览器访问“http://localhost:8018/getInfo”,结果如下图。
存在问题:老版本使用以下请求没问题,新版本就会报”status”:405,“error”:”Method Not Allowed”错误
curl -X POST "http://localhost:8016/actuator/bus-refresh"
解决:访问http://localhost:8016/actuator查看监控的端点路径,发现已经变为http://localhost:8016/actuator/busrefresh
{
"_links": {
"self": {
"href": "http://localhost:8016/actuator",
"templated": false
},
"health": {
"href": "http://localhost:8016/actuator/health",
"templated": false
},
"health-path": {
"href": "http://localhost:8016/actuator/health/{*path}",
"templated": true
},
"info": {
"href": "http://localhost:8016/actuator/info",
"templated": false
},
"busrefresh": {
"href": "http://localhost:8016/actuator/busrefresh",
"templated": false
},
"busrefresh-destinations": {
"href": "http://localhost:8016/actuator/busrefresh/{*destinations}",
"templated": true
}
}
}
11.7.2 Spring Cloud Bus 动态刷新配置(定点通知)
-
定点通知:不再通知所有的 Config 客户端,而是根据需求只通知其中某一个 Config 客户端。
-
使用 Spring Cloud Bus 实现定点通知的方法简单,只要我们在发送 POST 请求时使用以下格式即可。
http://{host}:{port}/actuator/busrefresh/{destination}
-
参数说明如下:
- {host}: 表示 Config 服务端的主机地址,既可以是域名,也可以是 IP 地址。
- {port}:表示 Config 服务端的端口号.
- {destination}:表示需要定点通知的 Config 客户端(微服务),由 Config 客户端的服务名(spring.application.name)+端口号(server.port)组成,例如只通知 microservice-cloud-config-client-8017 刷新配置,则取值为 microServiceCloudConfigClient:8017。
-
测试下 Spring Cloud Bus 动态刷新的定点通知。将配置文件application.yml中修改如下。然后提交仓库
-
在命令行窗口,使用以下命令向 microservice-cloud-config-client-8017 发送一个 POST 请求。
curl -X POST "http://localhost:8016/actuator/busrefresh/microServiceCloudConfigClient:8017"
- 使用浏览器访问“http://localhost:8017/getInfo”,结果如下图。
- 使用浏览器访问“http://localhost:8018/getInfo”,结果如下图。
下一篇:SpringCloud-31-Spring Cloud Config微服务与配置文件解耦
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/123793.html