Spring Cloud Config配置刷新存在的问题

spring-cloud-bus项目结构

spring-cloud-bus是用来实现服务间异步通信的服务总线,有基于kafka和rabbitmq的两个实现。

kafka和rabbitmq的消息处理逻辑本身也被抽象成了spring-cloud-stream,所以就有了上图中的依赖结构

spring-cloud-config-monitor一个通过spring-cloud-bus实现配置实时更新的依赖库。

spring-cloud-config-monitor架构

monitor一般是作为config-server的一个依赖库放在config-server上,这个库里提供了一个PropertyPathEndpoint的Controller接口。流程大致如下:

1、使用者在gitlab上修改并提交配置

2、gitlab在收到新的push后,把调用预先配置的webhook接口。这个webhook接口一般就是monitor提供的http接口。通过这个接口把git的push事件发送给monitor。

3、monitor收到事件后,解析事件中修改的文件,广播一个RefreshRemoteApplicationEvent事件到eventbus。这个事件有三个字段。

public abstract class RemoteApplicationEvent extends ApplicationEvent {
    private static final Object TRANSIENT_SOURCE = new Object();
    // 事件由哪个服务发送的
    private final String originService;
    // 事件发送给哪个服务,支持"**"的通配符,表示所有服务都接受这个事件
    private final String destinationService;
    // 事件ID
    private final String id;
    ...
}

4、所有依赖了eventbus的服务会收到这个Refresh事件,根据事件中的destinationService字段判断,这个事件是否需要处理,如果匹配成功,会由RefreshListener接受并处理这个事件。

5、RefreshListener中会调用ContextRefresher,拉取最新的配置,并更新Environment,重建所有加了@RefreshScope注解的Bean。

SpringBus的几个配置

spring:
  cloud:
    bus:
      enabled: true
      refresh:
        enabled: true
      env:
        enabled: true
      ack:
        enabled: true
      trace:
        enabled: false

1、refresh代表是否要接受远程EventBus发送过来的RefreshRemoteApplicationEvent事件。事件由RefreshListener处理。处理过程中,会从config-server拉取最新配置,并发送EnvironmentChangeEvent通知ConfigurationPropertiesRebinder刷新配置Bean

2、env是用来刷新部分配置的,事件里面要提供刷新的namevalue值。

3、ack是收到EventBus远程发来的事件后,是否返回确认事件。

4、trace是用来记录这些事件的,目前SpringCloud没有实现,只是打了debug日志。但是SpringCloud提供了HttpTraceRepository接口,后期可能会扩展。

存在的问题

1、如果config-server存在多个实例,webhook没办法广播到多个config-server实例,config-server本地备份的git仓库如何更新。如果有实例没有更新,就会导致第5步,拉取不到最新的配置。

2、gitlab中通常只配置一个webhook,测试、预发、生产环境的config-server怎么能都收到这个配置进行仓库的更新。

解决方案一

1、首先mq必须全局共享,开发、测试、预发、生产都用同一套mq

2、gitlab中配置的webhook是生产环境的config-server,收到push事件后,根据修改的文件提取出来环境和应用,通知对应环境的config-server更新git仓库

3、对应环境的config-server更新git仓库完成后,需要返回响应,响应中需要带上该环境下其他的config-server实例的信息(这个信息可以从eureka中获取,eureka是环境隔离的)。

4、需要等其他的config-server都更新完成后,再推送Refresh事件到其他需要更新配置的服务,这个时候能保证所有的服务拉到的配置都是最新的

解决方案二

1、gitlab中配置多个环境的webhook,这要求各环境的config-server域名区分开

2、webhook调用接口后,config-server检查更新的文件是否涉及当前环境,如果没有不需要做任何处理,相反如果涉及当前环境执行第3步

3、发送事件给当前环境的所有config-server实例,更新完成后返回确认

4、收到所有的确认后再由config-server发送Refresh事件到需要更新配置的服务

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值