官方文档地址为:http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#_serving_alternative_formats

文中例子我做了一些测试在:http://git.oschina.net/dreamingodd/spring-cloud-preparation

官方项目:https://github.com/spring-cloud-samples/config-repo

6.提供替代格式

由于Spring应用直接映射到环境抽象,来自环境链接的默认JSON格式完全适用于Spring应用的消费。如果愿意,开发人员可以通过给资源路径加上后缀的方式来使用YAML或Java属性来消费同样的数据。这对于不关心JSON链接返回结构的应用消费或其提供的额外元数据可能很有帮助,例如一个不使用Spring的应用就可以直接用这种方式。

YAML和属性表示有一个额外的标识(作为布尔查询参数resolvePlaceholders提供)用于标记标准Spring ${}格式的源文件中的占位符,在渲染之前尽可能在输出中解析。对于不了解Spring占位符约定的消费者来说,这是一个有用的功能。

注意 使用YAML或属性格式有一些限制,主要是与元数据的丢失有关。JSON格式是一个属性源的有序列表结构,例如,名称与源相关联。即使属性值有多个源,而且源属性文件的名称已丢失,YAML和属性表会合并成一个映射。YAML表示不必是后端仓库中YAML源的忠实表示:它由明文属性源的列表构成,而且必须对密钥的形式作出假设。

7.Serving Plain Text 提供明文

应用程序根据环境可能需要通用的纯文本配置文件,而不是环境抽象(或YAML中的其他替代表示或属性格式)。配置中心提供这些附属链接,/{name}/{profile}/{label}/{path},其中的"name","profile"等的含义与常规环境链接相同,只有"path"是一个文件名(如log.xml)。此链接的源文件通过和环境链接同样的方式定位:与属性或YAML文件具有相同的搜索路径,但它只匹配符合的第一个,而不是聚合所有匹配的资源。

当定位了一个源之后,有效环境中的普通格式(${...})的占位符解析为应用名称,profile和提供的label。资源链接和环境链接以这种方式紧密结合。例如,当存在这样的Git(或SVN)仓库:

application.yml nginx.conf

nginx.conf像这样:

server {
    listen              80;
    server_name         ${nginx.server.name};
}

而application.yml像这样:

nginx:
  server:
    name: example.com
---
spring:
  profiles: development
nginx:
  server:
    name: develop.com

然后/foo/default/master/nginx.conf resource像这样:

server {
    listen              80;
    server_name         example.com;
}

而/foo/development/master/nginx.conf像这样:

server {
    listen              80;
    server_name         develop.com;
}

注意 就像环境配置的源文件一样,"profile"是用来解析文件名的,因为如果开发人员需要一个靠profile指定的文件,那么/sth/development/sth/logback.xml将被解析为logback-development.xml(而不是logback.xml)。

8. 嵌入配置中心

配置中心最好独立运行。但若需要嵌入其他应用,也只需要@EnableConfigServer注解。这种情况下,有一个可选属性-spring.cloud.config.server.bootstrap很有用,它是一个服务器是否从自己的远程仓库配置自己的标志。由于它拖慢启动,默认是关闭的,但当嵌入其他应用时,与其他应用一样初始化就说得通了。

注意 很明显,记住如果使用bootstrap标志,配置中心将需要在bootstrap.yml配置其名称和仓库URI。

可以设置spring.cloud.config.server.prefix-如"/config",来修改服务器的链接地址,以为前缀下的资源提供服务。前缀应以"/"开始并不以"/"结束。适用于配置中心的@RequestMappings(即,在Spring Boot前面的server.servletPath和server.contextPath下)。

如果需要直接从后端仓库(不是配置中心)给应用读取配置,这基本上就是一个没有对外链接的内嵌配置中心。不使用@EnableConfigServer注解就可以彻底关闭对外链接(设置spring.cloud.config.server.bootstrap=true)。

9.推送通知和Spring Cloud Bus

很多源代码仓库提供方(例如像Github,Gitlab或Bitbucket)都会通过webhook通知用户仓库的修改。开发人员可以通过提供方的用户接口来配置webhook,URL或一些感兴趣的事件。例如Github会使用包含一串commits的JSON格式POST到webhook,header中的"X-Github-Event"表示"push"。如果在spring-cloud-config-monitor库中加入依赖并在配置中心激活Spring Cloud Bus,那么"/monitor"链接就启用了。

当webhook被激活时,配置中心会发送一个RefreshRemoteApplicationEvent事件,针对于它认为已经发生改变的应用。变更检测可以进行策略化,但默认它只查找与应用程序名称匹配的文件的更改(例如,"foo.properties"针对于"foo"应用,"application.properties"针对于所以应用)。如覆盖该行为的策略为PropertyPathNotificationExtractor,它接受请求头和主题作为参数并返回一个变更的文件路径列表。

默认配置与Github,Gitlab以及Bitbucket都是开箱即用。除Github,Gitlab或Bitbucket的JSON通知之外,开发人员可以触发一个变更通知,通过使用form-encoded参数体path={name}POSTing到"/monitor"。这样做会向匹配"{name}"的应用发送广播(可以包含通配符)。

注意 需要配置中心和客户端应用激活spring-cloud-bus才能传输RefreshRemoteApplicationEvent。

注意 本地Git仓库默认检测文件系统变更(这种情况下不使用webhook,但一旦修改了配置文件,会广播刷新事件)。

10.Spring Cloud Config客户端

Spring Boot应用可以立即利用Spring Config服务端(或应用程序开发人员提供的其他外部属性源),并且还将获取与环境更改事件相关的一些其他有用功能。

配置第一个Bootstrap

这是任何在classpath中存在Spring Cloud Config客户端的应用的默认行为。当配置客户端启动时,它将绑定配置中心(通过bootstrap配置属性spring.cloud.config.uri)并使用远程属性源初始化Spring环境。

最终结果是所有希望消费配置中心的客户端应用都需要在bootstrap.yml(或环境变量)中存在一个服务器地址spring.cloud.config.uri(默认为"http://localhost:8888")。

发现第一个Bootstrap

如果使用DiscoveryClient实现,比如Spring Cloud Netflix和Eureka Service Discovery或者Spring Cloud Consul(Spring Cloud Zookeeper暂时不支持),那么可以按需将配置中心注册为Discovery Servcie,但是在默认的"Config First"模式中,客户端将不能利用这种注册。

如果希望使用DiscoveryClient来定位配置中心,开发人员可以通过设置spring.cloud.config.discovery.enabled=true(默认false)来实现。最终结果是客户端应用需要相应的服务发现配置的bootstrap.yml(或环境变量)。例如,使用Spring Cloud Netflix,需要定义Eureka服务器地址,例如在eureka.client.serviceUrl.defaultZone。这样做的代价是启动时一个额外的网络往返开销去定位服务注册,好处是只要发现服务是一个固定点,配置中心可以改变坐标。默认的服务ID为"configserver",开发人员可以通过spring.cloud.config.discovery.serviceId修改(在服务器上通常用spring.application.name修改)。

服务发现客户端实现全都支持某种元数据映射(例如Eureka的eureka.instance.metadataMap)。配置中心可能需要在注册元数据中配置一些额外的属性以便客户端能正确连接。如果配置中心使用HTTP Basic安全配置服务器,则可以将凭据配置为"username"和"password"。而且配置中心修改"confgPath"来设置context path。例子,对于一个身为Eureka客户端的配置中心:

bootstrap.yml

eureka:
  instance:
    ...
    metadataMap:
      user: osufhalskjrtl
      password: lviuhlszvaorhvlo5847
      configPath: /config

配置客户端快速失败

某些情况下,如果客户端无法连接服务器,可能需要让启动失败。若需要这种行为,设置bootstrap配置属性spring.cloud.config.failFast=true,客户端就会停止并抛出异常。

配置客户端重试

如果配置中心在应用启动时偶尔不可用,那么可以让应用在失败后进行重试。首先需要设置spring.cloud.config.failFast=true,然后需要将spring-retry和spring-boot-starter-aop加入classpath。默认会重试6次,初始间隔为1000ms,后续间隔指数为1.1。这些属性在spring.cloud.config.retry.*中设置。

提示 完全控制重试功能,要添加一个类型为RetryOperationsInterceptor,id为"configServerRetryInterceptor"的Bean。Spring Retry提供了一个RetryInterceptorBuilder,可以轻松创建这个Bean。

Locating Remote Configuration Resources 定位远程配置资源

配置中心提供来自/{name}/{profile}/{label}的属性源,在客户端APP中默认绑定的是

  • "name" = ${spring.application.name}
  • "profile" = ${spring.profiles.active} (actually Environment.getActiveProfiles())
  • "label" = "master"

以上都可以设置spring.cloud.config.*(星号就是"name","profile"和"label")来覆盖。"label"可以用来回滚到历史版本;使用默认的配置中心实现它可以是一个git label,branch名称或commit id。Label亦可用逗号分隔的列表形式提供,这种情况下列表值会一个一个试过来,直到成功为止。当在feature分支上工作时会比较有用,比方说,当开发人员需要将配置label和branch对齐时,同时又可选(例:spring.cloud.config.label=myfeature,develop)。

安全性

如果开发人员在服务端使用HTTP Basic安全,那么客户端只需要知道密码(用户名不是默认的话也需要)。开发人员可以通过config server URI或分离用户名和密码属性来实现,例:

bootstrap.yml

spring:
  cloud:
    config:
      uri: https://user:secret@myconfig.mycompany.com

or

bootstrap.yml

spring:
  cloud:
    config:
      uri: https://myconfig.mycompany.com
      username: user
      password: secret

spring.cloud.config.password和spring.cloud.config.username这两个属性值会覆盖任何URI提供的属性。

如果在Cloud Foundry开发APP的话,最好的方式是通过服务凭据来提供密码,比如在URI中,这样它甚至不需要在配置文件中存在。下面是一个在Cloud Foundry上用户提供的服务,本地运行,名为"configserver":

bootstrap.yml

spring:
  cloud:
    config:
      uri: ${vcap.services.configserver.credentials.uri:http://user:password@localhost:8888}

如果开发人员使用其他安全方式,可能就需要提供一个到ConfigServicePropertySourceLocator的RestTemplate(例:在bootstrap上下文中获取并注入一个)。

Health Indicator 健康指标

客户端支持Spring Boot的健康指标。不过也可以通过health.config.enabled=false来禁用。因为性能原因响应会被存到缓存。默认缓存生存5分钟。health.config.time-to-live属性可以修改。

提供一个自定义的RestTemplate

某些情况下,可以会需要自定义请求从客户端发送到配置中心。通常这涉及传递特殊的授权头来验证发送到服务端的请求。提供自定义的RestTemplate请按照以下步骤。

1.创建一个PropertySourceLocator实现的Bean。

CustomConfigServiceBootstrapConfiguration.java

@Configuration
public class CustomConfigServiceBootstrapConfiguration {
    @Bean
    public ConfigServicePropertySourceLocator configServicePropertySourceLocator() {
        ConfigClientProperties clientProperties = configClientProperties();
       ConfigServicePropertySourceLocator configServicePropertySourceLocator =  new ConfigServicePropertySourceLocator(clientProperties);
        configServicePropertySourceLocator.setRestTemplate(customRestTemplate(clientProperties));
        return configServicePropertySourceLocator;
    }
}

2.在resources/META-INF中创建一个spring.factories指定自定义配置类。

spring.factories

org.springframework.cloud.bootstrap.BootstrapConfiguration = com.my.config.client.CustomConfigServiceBootstrapConfiguration

Vault

当使用Vault作为配置中心的后端时,客户端需要提供令牌来向Vault获取数据。这个令牌是通过设置bootstrap.yml中的spring.cloud.config.token来提供的。

bootstrap.yml

spring:
  cloud:
    config:
      token: YourVaultToken

Vault

在Vault中嵌入密钥

Vault提供了将密钥嵌入存储值的功能。例如

echo -n '{"appA": {"secret": "appAsecret"}, "bar": "baz"}' | vault write secret/myapp -

此命令会将一个JSON对象写入Vault中。Spring访问这些值需要使用传统的点(.)注解。例如

@Value("${appA.secret}")
String name = "World";

上述代码将name变量设置为appAsecret。

 

dreamingodd原创文章,如转载请注明出处。

分类:

技术点:

相关文章: