Spring boot 如何更新多个spring配置实例客户端

Spring boot 如何更新多个spring配置实例客户端,spring-boot,spring-cloud,Spring Boot,Spring Cloud,SpringCloudConfigClient有助于在运行时更改属性。下面是两种方法 更新GIT存储库并在客户端应用程序中点击/刷新以获取最新值 通过将更新发布到/env,然后发布/refresh,直接更新客户端 这两种方法的问题在于,可能有多个客户端应用程序实例在CloudFoundry中运行,并且上述rest调用将到达任何一个实例,从而使应用程序处于不一致的状态 例如,POST to/env可能会命中实例1,并将旧数据留给实例2 我能想到的一个解决方案是,使用for循环不断地达到这些端点“n

SpringCloudConfigClient有助于在运行时更改属性。下面是两种方法

  • 更新GIT存储库并在客户端应用程序中点击/刷新以获取最新值
  • 通过将更新发布到/env,然后发布/refresh,直接更新客户端
  • 这两种方法的问题在于,可能有多个客户端应用程序实例在CloudFoundry中运行,并且上述rest调用将到达任何一个实例,从而使应用程序处于不一致的状态

    例如,POST to/env可能会命中实例1,并将旧数据留给实例2

    我能想到的一个解决方案是,使用for循环不断地达到这些端点“n”次,以确保所有实例都将被更新,但这是一个粗糙的解决方案。有没有更好的解决方案


    注意:我们正在私有PCF环境中部署应用程序。

    解决该问题的标准解决方案是Spring云总线。如果您的应用程序绑定到RabbitMQ服务,并且它们在类路径上有总线,那么将有其他端点/bus/env和/bus/refresh将消息广播到所有实例。有关详细信息,请参阅文档。

    请参见org.springframework.cloud.bootstrap.config.RefreshEndpoint代码:

    public synchronized String[] refresh() {
    Map<String, Object> before = extract(context.getEnvironment()
            .getPropertySources());
    addConfigFilesToEnvironment();
    Set<String> keys = changes(before,
            extract(context.getEnvironment().getPropertySources())).keySet();
    scope.refreshAll();
    if (keys.isEmpty()) {
        return new String[0];
    }
    context.publishEvent(new EnvironmentChangeEvent(keys));
    return keys.toArray(new String[keys.size()]);
    
    公共同步字符串[]刷新(){
    Map before=extract(context.getEnvironment()
    .getPropertySources());
    将配置文件添加到环境();
    设置关键点=更改(之前,
    提取(context.getEnvironment().getPropertySources()).keySet();
    scope.refreshAll();
    if(key.isEmpty()){
    返回新字符串[0];
    }
    publishEvent(新环境变更事件(键));
    返回keys.toArray(新字符串[keys.size()]);
    
    }


    这意味着/refresh endpoint首先拉git,然后刷新catch,并公开一个environmentChangeEvent,这样我们就可以像这样定制代码。

    谢谢Dave Syer,它起作用了,但并不完全有效。git推送和刷新反映在实例中,而不是步骤2环境属性的临时更改,即云总线POST/bus/env更新即使在POST总线/刷新之后也不会得到反映。发布后,我可以在/env response和on/bus/refresh中看到“manager”键中的值,我想要最新的值,但事实并非如此。有什么想法吗?不过组件在刷新范围内。这听起来可能是正确的行为。这就像您发送了/env请求,然后向单个实例发送了/refresh,不是吗?