2、在需要读取配置的类上增加 @RefreshScope 注解,我们是 controller 中使用配置,所以加在 controller 中。
@RestController @RefreshScope public class GitController { @Autowired private GitConfig gitConfig; @Autowired private GitAutoRefreshConfig gitAutoRefreshConfig; @GetMapping(value = "show") public Object show(){ return gitConfig; } @GetMapping(value = "autoShow") public Object autoShow(){ return gitAutoRefreshConfig; } }注意,以上都是在 client 端做的修改。
之后,重启 client 端,重启后,我们修改 github 上的配置文件内容,并提交更改,再次刷新页面,没有反应。没有问题。
接下来,我们发送 POST 请求到 :3302/actuator/refresh 这个接口,用 postman 之类的工具即可,此接口就是用来触发加载新配置的,返回内容如下:
[ "config.client.version", "data.env" ]之后,再次访问 RESTful 接口,:3302/autoShow 这个接口获取的数据已经是最新的了,说明 refresh 机制起作用了。
而 :3302/show 获取的还是旧数据,这与 @Value 注解的实现有关,所以,我们在项目中就不要使用这种方式加载配置了。
在 github 中配置 Webhook
这就结束了吗,并没有,总不能每次改了配置后,就用 postman 访问一下 refresh 接口吧,还是不够方便呀。 github 提供了一种 webhook 的方式,当有代码变更的时候,会调用我们设置的地址,来实现我们想达到的目的。
1、进入 github 仓库配置页面,选择 Webhooks ,并点击 add webhook;
2、之后填上回调的地址,也就是上面提到的 actuator/refresh 这个地址,但是必须保证这个地址是可以被 github 访问到的。如果是内网就没办法了。这也仅仅是个演示,一般公司内的项目都会有自己的代码管理工具,例如自建的 gitlab,gitlab 也有 webhook 的功能,这样就可以调用到内网的地址了。
使用 Spring Cloud Bus 来自动刷新多个端
Spring Cloud Bus 将分布式系统的节点与轻量级消息代理链接。这可以用于广播状态更改(例如配置更改)或其他管理指令。一个关键的想法是,Bus 就像一个扩展的 Spring Boot 应用程序的分布式执行器,但也可以用作应用程序之间的通信渠道。
—— Spring Cloud Bus 官方解释
如果只有一个 client 端的话,那我们用 webhook ,设置手动刷新都不算太费事,但是如果端比较多的话呢,一个一个去手动刷新未免有点复杂。这样的话,我们可以借助 Spring Cloud Bus 的广播功能,让 client 端都订阅配置更新事件,当配置更新时,触发其中一个端的更新事件,Spring Cloud Bus 就把此事件广播到其他订阅端,以此来达到批量更新。
1、Spring Cloud Bus 核心原理其实就是利用消息队列做广播,所以要先有个消息队列,目前官方支持 RabbitMQ 和 kafka。
这里用的是 RabbitMQ, 所以先要搭一套 RabbitMQ 环境。请自行准备环境,这里不再赘述。我是用 docker 直接创建的,然后安装了 rabbitmq-management 插件,这样就可以在浏览器访问 15672 查看 UI 管理界面了。
2、在 client 端增加相关的包,注意,只在 client 端引入就可以。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>3、在配置文件中增加 RabbitMQ 相关配置,默认的端口应该是 5672 ,因为我是用 docker 创建的,所以有所不同。
spring: rabbitmq: host: localhost port: 32775 username: guest password: guest4、启动两个或多个 client 端,准备来做个测试
在启动的时候分别加上 vm option:-Dserver.port=3302 和 -Dserver.port=3303 ,然后分别启动就可以了。
5、分别打开 :3302/autoShow 和 :3303/autoShow,查看内容,然后修改 github 上配置文件的内容并提交。再次访问这两个地址,数据没有变化。
6、访问其中一个的 actuator/bus-refresh 地址,注意还是要用 POST 方式访问。之后查看控制台输出,会看到这两个端都有一条这样的日志输出
o.s.cloud.bus.event.RefreshListener: Received remote refresh request. Keys refreshed7、再次访问第 5 步的两个地址,会看到内容都已经更新为修改后的数据了。