Spring Cloud Config 配置中心 - 自动刷新配置

git 上源码地址为:

https://github.com/IChampionZhang/spring-cloud-config-server-demo.git

https://github.com/IChampionZhang/spring-cloud-bus-demo.git

假定现在的 Eureka 注册中心、配置中心以及客户端应用的简约配置如下所示:

Eureka Server 端口:10000

配置中心端口:9002

配置中心名称:config-server

客户端应用端口:10005

客户端应用名称:busdemo(busdemo-dev 表示的是开发环境的配置文件)

后面的请求都是基于上面这样的端口设定来执行的。

配置中心 config-server 搭配 Git 使用之后,当有新的配置更新时(假定这次更新叫做 A,更新内容是修改age的值:age from 28 to 30),我们首先会将更新A push 到 git 上面去,此时如果通过 config-server 的端口来访问 busdemo-dev.yml 文件的话,确实可以得到更新A,但是如果我们将监听 config-server 的客户端应用 SpringCloudBusDemoApplication 启动后,访问它的启动端口例如10005:http://localhost:10005/actuator/env 时却发现无法得到更新A 的更新内容。那么客户端如何才能得到最新的配置信息呢?
 

访问客户端应用的 /actuator/refresh 端点刷新配置

首先可以通过访问 http://localhost:10005/actuator/refresh 来将 SpringCloudBusDemoApplication 的配置刷新,再次访问 http://localhost:10005/actuator/env 就可以看到更新 A 的内容,但是这样的操作仅仅可以更改 /actuator/env 的数据,对于正在运行中的 SpringCloudBusDemoApplication,如果引用了更新 A 的更新内容 age,那么访问 SpringCloudBusDemoApplication 应用时得到的 age 还是 28,例如访问 SpringCloudBusDemoApplication 的 http://localhost:10005/consumer 

启动后的客户端应用配置刷新:热更新

对于这种热更新的情况,我们可以在客户端应用 http://localhost:10005/consumer 请求对应的 Controller上面加上一个 @RefreshScope 注解,当 http://localhost:10005/actuator/env 的访问得到更新时,应用内的访问也会得到更新。



 

总结:当修改配置文件提交到 git 上面去,作为配置中心 config-server(访问config-server:http://localhost:9002/busdemo/dev) 会第一时间收到更新,而依赖于配置中心的 http://localhost:10005/actuator/env 需要通过 http://localhost:10005/actuator/refresh 手动刷新;而对于应用内的数据则需要通过在 controller 上添加 @RefreshScope 注解来使得应用的数据可以与 http://localhost:10005/actuator/env 的数据同步更新

Spring Cloud Bus 自动刷新的工作原理

spring cloud bus 的 spring.factories 里面的 BusAutoConfiguration 使用 EventListener 定义了监听 RemoteApplicationEvent 类型事件的监听器 acceptLocal 方法,该监听器收到事件之后就会将事件发送到 springCloudBusOutput 这个通道中:

 

 

同时也配置了 acceptRemote 来监听 springCloudBusInput 上面的流数据

另外 Spring Cloud Bus 还提供了 bus-refresh 这个端点来发出一个 RefreshRemoteApplicationEvent 事件,该事件是 RemoteApplicationEvent 类型,因此对于这个端点的请求将同时触发上面刚开始提到的 acceptLocal 方法(监听的是 RemoteApplicationEvent 类型事件);

另外还会触发 RefreshListener 监听器的 onApplicationEvent 事件从而又会触发另外两个类型的事件:EnvironmentChangeEvent 和RefreshScopeRefreshedEvent 来对应用本身的环境配置进行刷新

 

Spring Cloud Bus - Bus Refresh 端点的使用

上面的过程需要人工的去对每个部署的应用执行一次应用端的请求:http://localhost:10005/actuator/refresh 实在是不方便,那有没有更方便的方式呢?

通过上面对 Spring Cloud Bus 的简短介绍,我们可以想到:通过发出 post 请求到配置中心端的 bus-refresh 这个端点来发布一个刷新的事件到 bus 上,另外一端的客户端应用也要导入 bus 并且配置好 bus 通道,客户端应用在接收到来自配置中心发出的刷新事件后开始重新从 config-server 读取最新配置。

你可以通过调用 http://localhost:9002/actuator/bus-refresh 对所有监听 bus 应用进行更新,也可以调用 http://localhost:9002/actuator/bus-refresh/busdemo 来对单个应用进行配置更新

Spring Cloud Config Monitor 的使用

除了使用 Spring Cloud Bus 本身提供的 Bus Refresh 端点之外,我们还可以在 pom.xml 文件中引入 Config Monitor:

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-monitor</artifactId>
</dependency>

通过 Config Monitor 提供的 /monitor 这个路径并附上body:{"path":"busdemo"} 来发布一个 RefreshRemoteApplicationEvent 事件(上面 Spring Cloud Bus 自动刷新的工作原理 中有提到)从而对本地 config-server 配置进行更新并且通过 Bus 将刷新事件发送到消息通道中,客户端应用通过监听消息通道中的流数据从而收到刷新事件,具体可以查看 Config Monitor 的 jar包中 spring.factories 提到的 EnvironmentMonitorAutoConfiguration 配置以及 PropertyPathEndpoint 这个Controller的作用

以下是使用 Postman 模拟的 post 请求:

另外如果将配置中心端以及客户端 log.level 设置为 DEBUG 级别,可以看到如下消息:

自动刷新配置

以上还是需要人工的调用 config-server 端的配置,那么如何才能真正实现自动刷新配置呢?通过上面对于 Spring Cloud Bus 提供的 Bus-Refresh 端点以及 Spring Cloud Config Monitor 的 /monitor 路径的介绍,配合使用 git 上的 webhook 就可以实现自动刷新配置的功能:当你把新的配置文件 push 到 git 上之后,git 监听到这个 push 的动作就会将这个事件发送到你设定的 url 来进行通知。

 

配置中心相关配置

以下是配置中心的配置文件:

server:
  port: 9002
 
spring:
  application:
    name: config-server-demo
#  security:
#    user:
#      name: user
#      password: 123456
  cloud:
    stream:
      binders:
        rabbit1:
          type: rabbit
          environment:
            spring:
              rabbitmq:
                host: rabbitmq 服务器ip
                port: 5672
                username: admin
                password: admin
                publisher-confirms: true
      bindings:
        springCloudBusInput: # spring cloud  bus 默认的输入通道名
          binder: rabbit1
        springCloudBusOutput: # spring cloud bus 默认的输出通道名
          binder: rabbit1
    bus:
      destination: bus-queue # spring cloud bus 的目的地(也就是 exchange 的名字)
      trace:
        enabled: true
    
    config:
      server:
        git:
          uri: https://github.com/IChampionZhang/spring-cloud-config-server-demo.git
          username: github 用户名
          password: github 密码
          basedir: git 上拉取到的配置文件的本地存放目录
          clone-on-start: true
          proxy: # 不需要代理可以去掉下面这段
            http:
              host: 代理 ip
              port: 代理端口
            https:
              host: 代理 ip
              port: 代理端口
        encrypt:
          enabled: true # 启用加密功能,秘钥的key在 bootstrap.xml 文件中,应用启动
                        # 后可以访问 http://localhost:9002/encrypt post 请求的方
                        # 式输入要加密的内容,也可以访问 http://localhost:9002/decrypt 
                        # post 的请求的方式输入需要解密的密文

eureka: # 注册中心配置
  client:
    service-url:
      defaultZone: http://localhost:10000/eureka/
     
management: # 开放所有的端点
  endpoints:
    web:
      exposure:
        include: "*"
          

配置中心的 pom 文件中的关键依赖:

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

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

客户端应用相关配置

以下是客户端应用配置文件:

spring:
  cloud:
    config:
      name: busdemo
      uri:
      - http://localhost:9002/ # 配置中心地址
  profiles:
    active: dev

下面是它的 pom 文件中的关键依赖:

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

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-config</artifactId>
</dependency>

 

最后附上文章描述图:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值