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,\
Прежде чем делать какие-либо запросы, я должен быть в состоянии изучить PropertySource
s и найдите любые свойства, которые вернул бы первый успешный загрузчик. Если бы он присутствовал, я бы попытался добавить дополнительную метку или профиль в 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.