java - Spring Cloud Binder : mitigating cost of double bootstrap

标签 java spring-boot spring-cloud-config spring-cloud-bus

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

我从this answer了解到为什么 Cloud Client 应用程序使用父级 SpringBootApplication 的 Config 引导,然后在 Cloud Bus 绑定(bind)后再次引导。我没意见。

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

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

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

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

(我可以从配置/服务器端解决,但这有点绝望,而且我不愿意尝试管理状态 - 跨两个恰好相隔约 20 秒的完全相同的请求。)


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

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

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

我猜这可行,但是否有更清洁/更 Spring Boot-y 的方式?

最佳答案

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

用于控制 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;
    }
}

已经有第二次引导机会,完全忽略它并再次返回相同的 PropertySource 似乎有点粗鲁 - 但在我们的情况下这很好。它可以防止我们两次访问配置服务器并浪费地生成凭据。

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

关于java - Spring Cloud Binder : mitigating cost of double bootstrap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53597052/

相关文章:

java - 接口(interface)和抽象类共享相同的方法

java - Jpa 存储库查询 - java.lang.Object;不能转换到模型

java - Spring 应用程序中的字段未初始化

spring-boot - Spring Boot 2 OIDC (OAuth2) 客户端/资源服务器不在 WebClient 中传播访问 token

java - 需要有关 Java 8 流逻辑的帮助

java - 在类 'location' 中找不到属性 'org.springframework.beans.factory.config.PropertyPlaceholderConfigurer' 的 setter

java - 如何动态添加目录/文件(searchLocations)供Spring-Cloud配置服务器观看?

spring-boot - 已解决 [org.springframework.cloud.config.server.environment.NoSuchLabelException : No such label: master]

java - 在 bootstrap.properties 文件中配置 Spring Cloud Config 的机制是什么?

java - Lucene的FloatField和FloatDocValuesField有什么区别?