天天看点

Spring Cloud Bus的使用

微服务项目中,使用到Spring Cloud Config来托管各模块的配置文件后,会有一个尴尬的问题 : Config服务端并不能动态的感知Git上配置文件的变化,当git上配置文件更新后,如果不采取其它措施,就只能重启相关应用,从而达到配置的更新,那么如何不重启项目, 就能实现配置的更新呢? 我们可以使用 Spring Cloud Bus来完成 。那么对项目改造如下:

1) 修改Config服务器端代码。

  pom文件引入坐标: (注意:我父工程中定义了boot 、cloud版本,每个子模块都依赖父工程,文章最后会附上父工程pom)

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-bus</artifactId>
</dependency>
           

 修改配置文件:(加入rabbitmq地址,以及暴露消息总线地址)

spring:
  .....
  rabbitmq:
    host: 127.0.0.1  # 其他采用默认
management:  # 暴露消息总线的地址
  endpoints:
    web:
      exposure:
        include: bus-refresh  # 固定写法
           

 2) 修改Config客户端代码

 pom文件引入坐标:(除了bus外还需要引入actuator )

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-bus</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
           

  注: 该版本引入 spring-boot-starter-actuator 可能会无法启动,报错信息如下:

Spring Cloud Bus的使用

 那么一般是jar包冲突所致,本人使用时就有这种情况,后将springboot版本提升后,启动正常(刚开始使用的版本是2.0.1.RELEASE ,后改至2.0.2.RELEASE ,2.0.3.RELEASE 也可以 )

 修改配置文件:

同config服务器端,这里只需引入rabbitmq的配置即可。

服务器端和客户端重启后,就会生效了,此时客户端就会监听rabbitmq中的关于配置更新的消息,当git上配置文件改变后,对于运维人员来说,只需要 发送请求:  http://localhost:12000/actuator/bus-refresh (调用spring ckoud bus中内置post请求,向消息队列发送消息) ,客户端就会自动更新配置,从而达到无须重启项目就实现配置更新的效果。

另外,需要说明的是,此种方式对于自定义的配置并不适用,可以通过@RefreshScope注解来使自定义配置适用。测试如下:

 自定义配置:

Spring Cloud Bus的使用

 测试代码如下:在controller中使用@Value取值。

Spring Cloud Bus的使用

测试findAll方法:输出如下:

Spring Cloud Bus的使用

修改了配置文件中的自定义配置后,发送post请求,测试findAll方法,会发现输出依旧, 

可以在controller上添加 @RefreshScope 注解,就能达到自定义配置也能刷新的效果了。

Spring Cloud Bus的使用

再次修改git上的配置文件:

Spring Cloud Bus的使用

 不需要重启项目,postman 发送请求:

Spring Cloud Bus的使用

再次测试findAll接口:控制台打印如下:

Spring Cloud Bus的使用

附: maven父工程的pom文件:

<parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>2.0.2.RELEASE</version>
     <relativePath />
</parent> 
<dependencyManagement>
......
   <dependencies>
        <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-dependencies</artifactId>
           <version>Finchley.SR2</version>
           <type>pom</type>
           <scope>import</scope>
        </dependency>
   </dependencies>
</dependencyManagement>
           

2020/04/19(补充):

 上述 使用postman向config服务端发送post请求(http://localhost:12000/actuator/bus-refresh) ,将会刷新连接在该config服务端下的所有客户端配置,事实上,也可以仅刷新指定客户端 ,在命令后加入服务名、端口即可.

eg: 微服务 config-client-3355、config-client-3366 是连接在config-3344服务端下的两个客户端,此时仅仅想刷新3355的配置,就可以发送如下命令:

curl -X POST  "http://localhost:3344/actuator/bus-refresh/config-client:3355"

继续阅读