🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ## **1. Spring Cloud Bus 解决的问题** ### 1.1 **疑问: 当我们更新 GitHub 中的配置文件内容后, Config 客户端服务是否会及时更新的配置内容呢?** * **测试:** 修改config客户端,microservice-config-application.yml配置文件的prod的端口号 ![](https://img.kancloud.cn/75/2c/752cb90e992b96e6a56fc0c9af263312_798x296.png) git配置 ![](https://img.kancloud.cn/19/99/1999fae40d7c18fe77bc357e9b8876d0_303x179.png) **将端口配置改成4010** ![](https://img.kancloud.cn/71/ef/71ef140fe9606d611db5770b36b1bd67_687x589.png) **但是端口的修改没有生效,还是原来的4002** ![](https://img.kancloud.cn/81/7b/817b63909b132818b66624e0d552dfc9_548x119.png) * **结果** 重启config客户端后,配置生效 ![](https://img.kancloud.cn/7b/d3/7bd3e85294d65a70267255debcc41ae9_525x129.png) * **解决:** 如果希望在不重启微服务的情况下更新配置如何来实现呢? 我们使用 Spring Cloud Bus 来实现配置的自动更新。 ## **2. Spring Cloud Bus介绍** 1. **Spring Cloud Bus 翻译为消息总线。** 大家可以将它理解为管理和传播所有分布式项目中的消息即可。 2. Spring Cloud Bus本质是**利用了MQ的广播机制** ***在分布式的系统中传播消息,目前常用的有Kafka和RabbitMQ。*** 3. 利用Bus的机制可以做很多的事情,其中配置中心客户端刷新就是典型的应用场景之一,我们用一张图来描述Bus在配置中心使用的机制。 ![](https://img.kancloud.cn/75/99/7599853401c13dcf1e599e33afd1b93f_700x345.png) ## **3. Spring Cloud Bus实践** ### 3.1 应用服务端配置 **1. 应用服务端配置pom,添加依赖** ``` <!--Bus 与 rabbitMQ依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> <!--监听器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> ``` **2. 修改 bootstrap.yml添加** ``` spring: rabbitmq: host: localhost port: 5672 username: guest password: guest # 暴露触发消息总线的地址 management: endpoints: web: exposure: include: bus-refresh ``` 3. 修改git上的microservice-config-product.yml ![](https://img.kancloud.cn/19/c0/19c027e6f5990a5dcf43c6b7492d3a82_663x208.png) 改为 ![](https://img.kancloud.cn/c8/4b/c84b0a94d912a627a0200d439c0a8878_364x141.png) 但是Eureka注册名称很明显,没有改过来,一定要重启吗? ![](https://img.kancloud.cn/91/9c/919cb5d43a9914f8e6182017360819bf_827x254.png) **4. 使用 postman工具发送配置更新请求** 发送 POST 请求: http://localhost:8001/actuator/bus-refresh发送请求后,会向 rabbitmq 队列发送数据,就会被监听到进行更新服务配置信息 ![](https://img.kancloud.cn/fc/11/fc1154660d42291ba2865be6aa9d96c9_915x191.png) 配置很快就生效了 ![](https://img.kancloud.cn/77/c1/77c1a59097d3ea6a71aad71463401bd3_1204x250.png) ### **3.2 自定义类中读取配置实战** **1. 修改GitHub上的配置** 修改GitHub上的 microservice\-config\-product.yml 配置文件,增加自定义配置信息: ``` emp: name: tuna ``` **2. 用@Value注解获取配置** ~~~ @Value("${emp.name}") private String name; @GetMapping("/emp") public String getEmpName() { return name; } ~~~ **3. 访问测试** 注意:当@Value注解去取配置时,如果配置文件没有加这个配置,则程序启动不起来,并报解析错误 ![](https://img.kancloud.cn/42/74/4274f612e599803e820ea0b6aaf121eb_354x124.png) 已经读取到了配置 **4. 修改配置** ``` emp: name: tuna ``` 改成 ``` emp: name: fish ``` 使用 postman工具发送 POST 请求: http://localhost:8001/actuator/bus-refresh,发现并没有生效 ![](https://img.kancloud.cn/3a/10/3a1001300347e27900e4e4c477216f22_394x136.png) ### **5. 自定义配置需要 在controller上加 `@RefreshScope`注解支持** 是因为需要在 ProductController 上添加 @RefreshScope 注解 ,用于刷新配置 ~~~ package com.tuna.springcloud.server.controller; import com.tuna.springcloud.common.entities.Product; import com.tuna.springcloud.server.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.*; import java.util.List; @RefreshScope @RestController public class ProductController { 。。。 @Value("${emp.name}") private String name; @GetMapping("/emp") public String getEmpName() { return name; } } ~~~ **还原配置,重启应用服务端** 再次post更新请求,生效 ![](https://img.kancloud.cn/2d/bc/2dbc8fa85fbcc9ae378197085b40b07b_444x107.png) ## 4.修改数据源实战 1\. 先访问 http://localhost:8001/product/get/1,发现当前获取了 springcloud\_db01 库的数据 ![](https://img.kancloud.cn/6d/76/6d766a6ee3962bfa64865eea49daf713_479x158.png) 2\. 修改GitHub上的 microservice\-config\-product.yml 配置文件,将 profile: dev (开发环境) 的 库名 改 为 springcloud\_db02 ![](https://img.kancloud.cn/a0/86/a086244a1ff4846571dde79c4382457a_784x240.png) 3\. 使用 postman工具发送 POST 请求: http://localhost:8001/actuator/bus-refresh 4\. 访问 http://localhost:8001/product/get/1,发现依然是 springcloud\_db01 库的数据, 发现并没有刷新配置。 ![](https://img.kancloud.cn/31/8b/318bf95179577b4244b6e67ec03d6ecf_501x123.png) ### 4.1 自定义Druid配置类 ~~~ @Configuration public class DruidConfig { @RefreshScope //刷新配置 @ConfigurationProperties(prefix = "spring.datasource") @Bean public DataSource druid() { return new DruidDataSource(); } } ~~~ ### 4.2 测试 现在取得是数据库2 ![](https://img.kancloud.cn/80/00/8000565c26bf9e99e41ce5b16bd89e1e_472x113.png) 修改配置成数据库1,并发送更新消息http://localhost:8001/actuator/bus-refresh 再次请求服务端,不用重启,数据库连接立即生效了 ![](https://img.kancloud.cn/34/42/34420acd901725fe9465a50496ec012c_512x129.png)