Spring Cloud Binder:减轻双倍成本 bootstrap

Spring Cloud Binder: mitigating cost of double bootstrap

我们使用 Spring Cloud Config (Dalston.SR5),云客户端使用 Spring Boot 2.x、Spring Cloud Bus,以及 Finchley.SR1.

我从 this answer 了解到为什么云客户端应用程序 bootstrap 具有父级 SpringBootApplication 的配置,然后在绑定云总线后再次使用。我没意见。

我的问题是有没有办法区分这两个bootstrap请求?

我问的原因是我们的 Config 服务器生成凭据并 returns 将它们发送给客户端进行身份验证。两个 bootstraps 意味着两套凭据,只使用其中一套,这是浪费。

据我所知,ConfigServicePropertySourceLocator 每次都发送相同的 bootstrap 负载,这让 Config 没有机会。

是否有覆盖/挂钩,以便我可以让 Config 知道不要第二次生成凭据?

(我可以从 Config/server 方面解决,但这会有点绝望,而且我不愿意尝试管理状态 - 跨越两个恰好是 ~ 20 秒的其他相同请求分开。)


我目前最好的想法是子类化 PropertySourceBootstrapConfiguration 并根据以下内容更新 spring.factories

# Bootstrap components
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.bootstrap.config.MyCountingPropertySourceBootstrapConfiguration,\

在发出任何请求之前,我应该能够检查 PropertySource 并查找第一个成功的 bootstrap 会返回的任何属性。如果存在,我会尝试在 ConfigServicePropertySourceLocator 中添加一个额外的标签或配置文件,以便我的配置服务器第二次获取。

我想这行得通,但是有没有更清洁/更多的 Spring 启动方式?

这个解决方案看起来既简单又非常有效。

用于控制 ConfigServicePropertySourceLocator 的新自动配置:

@Configuration
@AutoConfigureBefore(ConfigServiceBootstrapConfiguration.class)
public class ConfigPropertyLocatorConfiguration {

    @Bean
    @ConditionalOnProperty(value = "spring.cloud.config.enabled", matchIfMissing = true)
    public ConfigServicePropertySourceLocator configServicePropertySource(ConfigClientProperties properties) {
        return new CachingConfigServicePropertySourceLocator(properties);
    }
}

spring.factories:

org.springframework.cloud.bootstrap.BootstrapConfiguration=\
  autoconfigure.ConfigPropertyLocatorConfiguration

缓存定位器实现:

public class CachingConfigServicePropertySourceLocator extends
                                           ConfigServicePropertySourceLocator {

    private final static Logger LOG = getLogger("...");

    private PropertySource<?> cachedProperties;

    public CachingConfigServicePropertySourceLocator(ConfigClientProperties props) {
        super(props);
    }

    public PropertySource<?> locate(final Environment env) {
        if (cachedProperties == null) {
            cachedProperties = super.locate(env);
        }
        else {
            LOG.debug("Returning cached PropertySource for second bootstrap");
        }

        return cachedProperties;
    }
}

有第二次机会 bootstrap,完全忽略它似乎有点粗鲁 return 同样 PropertySource 再一次 - 但在我们的情况下,这是美好的。它可以防止我们两次访问配置服务器并浪费生成凭据。

无需更改 PropertySourceBootstrapConfiguration。云配置服务器没有变化。