使用Java而不是bootstrap.yml

时间:2015-06-22 20:03:48

标签: java spring-boot spring-cloud

我试图在我们的基础pom中构建代码,通过Eureka自动配置Spring Cloud Config服务器查找。我们这样做是为了避免为开发人员构建微服务模板化.yml属性。例如,我们想要java配置从这些属性触发的所有行为:

spring:
  application:
    name: MyMicroservice
  cloud:
    config:
      enabled: true
    server:
      prefix: /diagnostics/admin/config
    failFast: true
    discovery:
      enabled: true
      serviceId: echo

management:
  context-path: /diagnostics/admin

eureka:
  password: password
  client:
    serviceUrl:
      defaultZone: http://user:${eureka.password}@localhost:8761/eureka/
  instance:
    leaseRenewalIntervalInSeconds: 10
    statusPageUrlPath: /diagnostics/admin/info
    healthCheckUrlPath: /diagnostics/admin/health

经过多次试验,除了Eureka发现的配置服务器(导致没有覆盖的配置属性)之外,以下方法大部分都有效:

@Order(-1)
public class AdditionalBootstrapPropertySourceLocator implements PropertySourceLocator {

    @Override
    public PropertySource<?> locate(Environment environment) {
        Map<String, Object> theBootstrapYmlConfig = new HashMap<>();
        theBootstrapYmlConfig.put("spring.cloud.config.enabled", new Boolean(true));
        theBootstrapYmlConfig.put("spring.cloud.config.server.prefix", "/diagnostics/admin/config");
        theBootstrapYmlConfig.put("spring.cloud.config.failFast", new Boolean(true));
        theBootstrapYmlConfig.put("spring.cloud.config.discovery.enabled", new Boolean(true));
        theBootstrapYmlConfig.put("spring.cloud.config.discovery.serviceId", "echo");

        theBootstrapYmlConfig.put("management.context-path", "/diagnostics/admin");

        theBootstrapYmlConfig.put("eureka.client.serviceUrl.defaultZone", "http://user:password@localhost:8761/eureka/");
        theBootstrapYmlConfig.put("eureka.instance.leaseRenewalIntervalInSeconds", new Integer(10));
        theBootstrapYmlConfig.put("eureka.instance.statusPageUrlPath", "/diagnostics/admin/info");
        theBootstrapYmlConfig.put("eureka.instance.healthCheckUrlPath", "/diagnostics/admin/health");

        return new MapPropertySource("myExtraBootstrap", theBootstrapYmlConfig);    
    }    
}

我似乎也需要这个Bean:

@ConditionalOnWebApplication
@Configuration
@Import(EurekaClientAutoConfiguration.class)
public class WorkfrontDiscoveryClientConfigServiceBootstrapConfiguration {

    @Bean
    @ConditionalOnClass({ DiscoveryClient.class, ConfigServicePropertySourceLocator.class })
    @ConditionalOnMissingBean
    DiscoveryClientConfigServiceBootstrapConfiguration discoveryClientConfigServiceBootstrapConfiguration() {
        DiscoveryClientConfigServiceBootstrapConfiguration discoveryClientConfigServiceBootstrapConfiguration =
                 new DiscoveryClientConfigServiceBootstrapConfiguration();
        return discoveryClientConfigServiceBootstrapConfiguration;
    }

}

最后,我将两者放入spring.factories以确保它们被构造。问题是PropertySourceLocator永远不会用于在ConfigServicePropertySourceLocator中构造调用来检索属性。无论我做什么,我似乎无法匹配指定bootstrap.yml中的属性会产生的行为。

4天后编辑

这里的关键因素(和限制)是通过Eureka查找配置服务器的能力。在当前的Spring云版本(1.0.2)中,在Spring初始化周期中过早检索和构造属性源,以用于上面的config-lookup-through-eureka java属性源配置。此外,如果Eureka服务器在引导启动时很慢或不可用,则在Eureka最终出现时,永远不会重建Config服务器属性源。在我看来这是一个错误。

我通过消除通过Eureka查找配置服务器的概念解决了这一切,并在bootstrap.yml中要求这个最小配置:

spring:
  application:
    name: MyMicroservice
  cloud:
    config:
      uri: http://localhost:8888/diagnostics/admin/config

eureka:
  client:
    serviceUrl:
      defaultZone: http://user:password@localhost:8761/eureka/

然后在java AdditionalBootstrapPropertySourceLocator

中设置其余部分

30天后修改

Java配置引导属性仍然是一个挑战。我之所以这样做,是因为我正在开发一个没有模板化或代码生成的框架(弹簧启动的前提)。我已经添加了弹簧重试,并且客户端到配置被重试但是重新注册到Eureka却没有。这就是Eureka首先不得不为我抛弃的原因。我投票将spring-retry整合到Eureka注册过程中,所以我可以回到Eureka-first来获取我的框架。仍然在Spring Cloud 1.0.2上。

100天后修改

我们最终的更新地点。继续我们避免财产模板,在代码中实施策略和实践的咒语......并且在没有Eureka优先概念的情况下继续,我们放弃了PropertySourceLocator并简单地使用SpringApplicationRunListener,如下所示:

public class OurFrameworkProperties implements SpringApplicationRunListener {
  :
  public void started() {
    if (TestCaseUtils.isRunningFromTestCase()) {
      System.setProperty("spring.cloud.config.failFast", "false");
      System.setProperty("spring.cloud.config.enabled", "false");
      System.setProperty("eureka.client.enabled", "false");
    } else {
      // set production values same way
    }
  }
}

注意,每次Spring应用程序运行或获取Actuator refresh()时,这个开始()实际上会在spring代码中调用两次(一次不传递任何程序参数btw)。

2 个答案:

答案 0 :(得分:0)

如果PropertySourceLocator列在spring.factories中(我假设为BootstrapConfiguration),那么它必须是@Component(或者甚至是@Configuration )。

答案 1 :(得分:0)

您必须在boostrap.properties中设置此属性

eureka.instance.metadataMap.configPath: /your-app-name

并对此发表评论

#spring.cloud.config.uri=http://localhost:8888/

显然也应该是

eureka.client.serviceUrl.defaultZone: ${EUREKA_URI:http://localhost:8761/eureka}
eureka.client.instance.preferIpAddress: true

根据文档 https://cloud.spring.io/spring-cloud-config/multi/multi__spring_cloud_config_client.html#discovery-first-bootstrap