Spring Cloud Binder: снижение стоимости двойной загрузки

Мы используем Spring Cloud Config (Dalston.SR5), с облачными клиентами, использующими Spring Boot 2.x, Spring Cloud Bus и Finchley.SR1,

Из этого ответа я понимаю, почему приложение Cloud Client загружается с помощью Config для родительского SpringBootApplication и затем снова, когда Cloud Bus связан. Я в порядке с этим.

У меня вопрос, есть ли способ различить два запроса начальной загрузки?

Я спрашиваю, потому что наш сервер Config генерирует учетные данные и возвращает их клиенту для аутентификации. Две начальные загрузки означают два набора учетных данных, только один из которых используется, и это расточительно.

Насколько я могу судить, одна и та же полезная нагрузка начальной загрузки отправляется каждый раз ConfigServicePropertySourceLocator, что не дает Config никаких шансов.

Существует ли переопределение / перехват, чтобы я мог сообщить Config, что он не генерирует учетные данные во второй раз?

(Я мог бы заняться со стороны Config/server, но это было бы немного отчаянно, и я не хотел бы пытаться управлять состоянием - через два в остальном идентичных запроса, которые, как правило, находились на расстоянии ~ 20 секунд.)


Лучшая идея, которая у меня есть на данный момент - это подкласс PropertySourceBootstrapConfiguration и обновить spring.factories согласно:

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

Прежде чем делать какие-либо запросы, я должен быть в состоянии изучить PropertySources и найдите любые свойства, которые вернул бы первый успешный загрузчик. Если бы он присутствовал, я бы попытался добавить дополнительную метку или профиль в ConfigServicePropertySourceLocator для моего сервера конфигурации, чтобы забрать второй раз.

Я думаю, это могло бы сработать, но есть ли более чистый / более Spring Boot-y способ?

1 ответ

Решение

Это решение кажется простым и очень эффективным.

Новая автоконфигурация для контроля 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 еще раз - но в нашей ситуации это нормально. Это предотвращает нас от двойного подключения к серверу Config и расточительной генерации учетных данных.

Без изменений PropertySourceBootstrapConfiguration требуется. Никаких изменений на сервере Cloud Config.

Другие вопросы по тегам