版本:Dalston.RELEASE
Spring Cloud专注于提供一个可以覆盖其他的开箱即用的典型的可扩展的工具集.
Cloud Native是一种应用开发风格,鼓励在持续交付和价值驱动开发领域轻松采用最佳实践。相关的学科是建立12因素应用程序,其中开发实践与交付和运营目标相一致,例如通过使用声明式编程和管理和监控。Spring Cloud以多种具体方式促进了这些开发风格,起点是分布式系统中所有组件需要或需要时轻松访问的一系列功能.
Spring Boot中覆盖了许多这些功能,在Spring Cloud中构建。Spring Cloud提供了更多的两个依赖:Spring Cloud Context和Spring Cloud Commons。Spring Cloud Context为ApplicationContextSpring Cloud应用程序(引导上下文,加密,刷新范围和环境端点)提供实用程序和特殊服务。Spring Cloud Commons是一组在不同的Spring Cloud实现中使用的抽象和通用类(例如,Spring Cloud Netflix与Spring Cloud Consul)。
Spring Boot有一个关于如何使用Spring构建应用程序的看法:例如它具有常规配置文件的常规位置,以及用于常见管理和监视任务的端点。Spring Cloud构建在其上,并添加了一些可能系统中所有组件使用或偶尔需要的功能。
Spring Cloud 应用是被”bootstrap” context创建的,这个是主程序context的parent,还可以加在外部的资源,也可以解密本地的外部配置文件,两个context共享Environment,这个是任何Spring应用的外部文件.Bootstrap配置有很高的优先级,所以默认情况下是不可以被本地重写的.
bootstrap context使用了和main context不同的配置,所以你要使用boostrap.yml来代替application.yml(or .properties),保证boostrap和main配置有很好的分离,example:
bootstrap.yml
spring:
application:
name:foo
cloud:
config:
uri:${SPRING_CONFIG_URI:http://localhost:8888}
如果你的程序需要任何特定的服务器配置你可以在yml里设置spring.application.name
你可以完全禁用bootstrap进程,通过spring.cloud.bootstrap.enabled=false
如果你使用SpringApplication或者SpringApplicationBuilder来build你的application context,那么Bootstrap context会被添加作为Parent context,所以”main”context会包含额外的属性资源,和没有使用Spring Cloud Config比较的话,额外的属性资源如下:
因为这些优先级别规则,”bootstrap”这些entries会更加优先,但是要注意在bootstrap.yml中不包含任何data,这个优先级很低,可以设置为默认的.
你可以扩展context继承通过设置parent context为任何的你创建的ApplicationContext,假如使用它自己的接口,或者使用SpringApplicationBuilder便利的方法(parent(),child(),sibling()).bootstrap context将会作为你自己创建的大部分的parent,每一个context在继承关系中,都有一份自己的”bootstrap”属性资源(也有可能是空的),来避免被parent的后代不小心修改,每一个context在继承关系中,也可以有不同的spring.application.name,因此会路由到不同的资源如果有Config Server的话.正常的Spring Application context会是这样的属性:child 的properties会覆盖掉parent中同样的属性
注意SpringApplicationBuilder允许你共享一个Environment在一整个继承体系中,但是没有默认的,因此,兄弟context特别的不需要有同样的profiles或者property sources,即使他们将会共享同样的在parent中相同的东西
bootstrap.yml的位置可以使用spring.cloud.bootstrap.name来指定默认是”bootstrap”,或者spring.cloud.bootstrap.location,默认是empty,例如在系统properties,这些属性像是spring.config.*的变体,事实上,他们被使用建立bootstrap ApplicationConxt通过他们自己的Environment.如果有一个激活的profile,那么properties也会正常加载,就像Spring Boot一样.
通常property资源是通过bootstrap context远程添加到你的程序中像是Config Server,他们默认是不能被本地覆盖,除非在命令行中,如果你想要允许你的程序覆盖掉远程的properties用自己的系统properties或者配置文件,远程的资源需要授予这个权力,通过设置spring.clou.config.allowOverride=true,你在本地设置设个是没用的.一旦设置了那个标志,就会有更精细的粒度来设置控制远程属性和本地属性之间的位置,spring.cloud.config.overrideNone=true覆盖本地任何属性源,spring.cloud.config.overrideSystemProperties=false,如果只有系统属性和环境变量应该覆盖远程设置,但不是本地配置文件.
可以通过/META-INF/spring.factories的key org.springframework.cloud.bootstrap.BootstrapConfiguration来配置bootstrap做任何你想要做的事情.这是一个用@Configuration的类用逗号隔开的list用来创建context.任何的你在主程序的context中想要自动注入的beans都可以在这创建,还有一个特殊的@Beans,ApplicationContextInitializer,类可以用@Order标记,如果你想要控制他们的启动顺序
WARNING 要注意,当添加自定义的BootstrapConfiguration,这些类不会@ComponentSacnned被错误的添加到main程序的context中.可能不需要他们.需要使用一个单独的包用@ComponentScan或者@SpringBootApplication注释的配置类
bootstrap进程通过将初始化器注入SpringApplication实例(即正常的SpringBoot启动顺序,无论是作为独立程序运行还是部署在应用程序服务器中).首先,从的spring.factories中找到的类创建一个bootstrap context然后,在启动前将所有的@Beans类型的ApplicationContextInitializer添加到主程序SpringApplication中.
在bootstrap 进程中默认添加的额外的配置源是Config Server,但是你通过添加PropertySourceLocator的beans到bootstrap context中(通过spring.factories),添加额外的资源.你可以使用这个从不同的服务器插入额外的配置,或者从数据库
example
@Configuration
public class CustomPropertySourceLocator implements PropertySourceLocator{
@Override
public PropertySource> locat(Environment environment){
return new MapPropertySource("customProperty",Collections.singletonMap("property.from.sample.custom.source","worked as intended"));
}
}
这个Enviroment传递进来的是一个用于ApplicationContext将被创建的.即我们是提供额外的属性源,他已经具有正常的SpringBoot提供的属性源,因此可以用它们来定位特定的属性源Environment(例如spring.application.aname),按照默认配置服务属器的属性定位器中的配置.
如果你创建的jar里面有这个类,添加META-INF/spring.factories包含:org.springframework.cloud.bootstrap.BootstrapConfiguration=sample.custom.CustomPropertySourceLocator.然后”customProperty”这个PropertySource将会在包含这个jar的任何程序的类路径中
程序将会通过监听EnvironmentChangedEvent事件然后对变化做出反应(额外的ApplicationListeners可以作为一个@Beans被正常的添加).当一个EnviromentChangedEvent观察到它将具有已经改变的键值列表,并且程序将使用它们:
- 重新绑定@ConfigurationProperties上下文中的任何bean
- 设置任何属性的日志级别logging.level.*
注意,Config Client不会通过默认轮询来更改Environment,通常我们不建议用于检测更改的方法(尽管您可以使用 @Scheduled注释进行设置)。如果您有一个扩展的客户端应用程序,那么最好广播EnvironmentChangedEvent到所有的实例,而不是让它们轮询更改(例如使用Spring Cloud Bus)。
它EnvironmentChangedEvent涵盖了大量的刷新用例,只要您可以实际更改Environment 和发布事件(这些API是公开的,并且是Spring的一部分)。您可以@ConfigurationProperties通过访问/configprops 端点(正常的弹出启动程序功能)来验证更改是否绑定到 bean 。例如,一个 DataSource可以maxPoolSize在运行时改变(DataSource由Spring Boot创建的默认是一个 @ConfigurationPropertiesbean),并且动态增加容量。重新绑定@ConfigurationProperties不会覆盖另一大类用例,您需要更多的控制刷新,以及需要更改的原则在整体上 ApplicationContext。解决我们所关心的问题 @RefreshScope。
当配置改变时,一个被@RefreshScope标记的Spring的@Bean将会获得特殊的对待.
这解决了状态bean在初始化时只注入配置的问题。例如,如果DataSource在数据库URL被改变时有一个打开的连接Environment,我们可能希望这些连接的持有者能够完成他们在做什么。然后下一次有人从游泳池借用一个连接,他得到一个新的URL.
刷新范围bean是在使用时初始化的懒惰代理(即当调用一个方法时),并且作用域作为初始值的缓存。要强制bean重新初始化下一个方法调用,您只需要使其缓存条目无效.
该RefreshScope是在上下文中的bean,它有一个公共的方法 refreshAll()通过清除目标缓存刷新范围内的所有bean。还有refresh(String)一种通过名称刷新单个bean的方法。此功能在/refresh端点(通过HTTP或JMX)中公开 。
@RefreshScope在@Configuration 类上工作(技术上),但它可能会导致令人惊讶的行为:例如,这并不 意味着@Beans该类中定义的所有内容都是自己的 @RefreshScope。具体来说,依赖于这些bean的任何东西都不能依赖它们在刷新启动时被更新,除非它本身处于@RefreshScope重新启动状态(重新刷新并重新注入依赖关系,那么它们将被重新启动)从刷新初始化@Configuration)。
Spring Cloud具有Environment用于在本地解密属性值的预处理器。它遵循与Config Server相同的规则,并通过相同的外部配置encrypt.。因此,您可以使用形式的加密值,{cipher}只要有一个有效的密钥,那么它们将在主应用程序上下文获得之前被解密Environment。要在应用程序中使用加密功能,您需要在您的类路径中包含Spring Security RSA(Maven协调“org.springframework.security:spring-security-rsa”),并且还需要JVM中强大的JCE扩展。
对于Spring Boot Actuator应用程序,还有一些额外的管理端点:
- POST /env更新Environment并重新绑定@ConfigurationProperties和记录级别
- /refresh用于重新加载bootstrap带上下文并刷新@RefreshScopebean
- /restart关闭ApplicationContext并重新启动它(默认情况下禁用)
- /pause和/resume调用的Lifecycle方法(stop()和start()上ApplicationContext)
服务发现,负载平衡和断路器等模式可以融合到一个普通的抽象层,可以由所有的Spring Cloud客户端使用,而不依赖于实现(例如通过Eureka或Consul的发现).
Commons提供@EnableDiscoveryClient注解。它通过META-INF/spring.factories寻找DiscoveryClient的实现。Discovery Client的实现将spring.factories在org.springframework.cloud.client.discovery.EnableDiscoveryClient密钥下添加一个配置类。实现的例子有DiscoveryClient:Spring Cloud Netflix Eureka,Spring Cloud Consul Discovery和Spring Cloud Zookeeper Discovery。
默认情况下,DiscoveryClient的实现将使用远程服务发现自动注册本地SpringBoot服务。这可以通过设置被禁用autoRegister=false在@EnableDiscoveryClient。
Commons现在提供了一个ServiceRegistry接口,它提供了一些方法register(Registration),deregister(Registration)并允许您提供自定义的注册服务。Registration是一个标记接口。
@Configuration
@EnableDiscoveryClient(autoRegister=false)
public calss MyConfiguration {
private ServiceRegistry registry;
public MyConfiguration(ServiceRegistry registry){
this.registry = registry;
}
//called via some external process,such as an event or a custom actuator endpoint
public void register(){
Registration registration = constructRegistration();
this.registry.register(registration);
}
}
每一个ServiceRegistry的实现有他自己的Registry实现.
默认情况下,ServiceRegistry实现将自动注册正在运行的服务。要禁用该行为,有两种方法。您可以设置@EnableDiscoveryClient(autoRegister=false)为永久禁用自动注册。您还可以设置spring.cloud.service-registry.auto-registration.enabled=false通过配置禁用该行为。
一个/service-registry驱动器的端点是通过共用设置。该端点依赖于Spring应用程序上下文中的一个Registration Bean。通过GET 调用/service-registry/instance-status将返回注册状态.相同的端点用String body发送POST请求将会修改当前的注册的值.请阅读ServiceRegistry实现的文档,以获取更新状态的允许值和为状态获取的值
RestTemplate可以使用ribbon自动配置.通过@LoadBalanced和使用@Bean可以创建一个负载均衡的RestTemplate
注意,一个RestTemplatebean不再通过自动配置创建。它必须由单个应用程序创建。
@Configuration
public calss MyConfiguration{
@LoadBalanced
@Bean
RestTemplate restTemplate(){
return new RestTemplate();
}
}
public class MyClass{
@Autowired
private RestTemplate restTemplate;
public String doOtherStuff(){
String results = restTemplate.getForObject("http://stores/stores",String.class);
return results;
}
}
URI需要使用虚拟主机名(即服务名称,不是主机名),Ribbon客户端用来创建完成的物理地址,参考RibbonAutoConfiguration获得更多如何创建RestTemplate的细节
RestTemplate可以配置负载均衡以重试失败的请求。默认情况下,该逻辑被禁用,您可以通过设置启用它 spring.cloud.loadbalancer.retry=true.负载平衡RestTemplate将符合与重试失败请求相关的一些功能区配置值。您可以使用的特性是client.ribbon.MaxAutoRetries, client.ribbon.MaxAutoRetriesNextServer和client.ribbon.OkToRetryOnAllOperations。请参阅功能区文档 ,了解属性的具体内容
注意 client在上面的例子中应该使用你的Ribbon客户端的名字代替
如果你想要一个RestTemplate没有负载平衡,创建一个RestTemplate bean并正常注入它。RestTemplate使用 @LoadBalanced在创建时访问负载平衡限定符@Bean
重要 请注意下面@Primary示例中的简单声明中的注释RestTemplate,以消除不合格@Autowired注入的歧义。
@Cinfiguration
public class MyConfiguration{
@LoadBalanced
@Bean
RestTmeplate loadBalanced(){
return new RestTemplate();
}
@Primary
@Bean
RestTemplate restTemplate(){
return new RestTemplate();
}
}
public class MyClass{
@Autowired
private RestTemplate restTemplate;
@Autowired
@LoadBalanced
private RestTemplate loadBalanced;
public String doOther Stuff(){
return loadBalanced.getForObject("http://stores/stores",String.class);
}
public String doStuff(){
return restTemplate.getForObject("http://example.com",String.class);
}
}
贴条 如果您看到像java.lang.IllegalArgumentException: Can not set org.springframework.web.client.RestTemplate field com.my.app.Foo.restTemplate to com.sun.proxy.$Proxy89尝试注入RestOperations或设置错误spring.aop.proxyTargetClass=true。
有时,忽略某些命名网络接口是有用的,因此可以将其从服务发现注册中排除(例如,在Docker容器中运行)。可以设置正则表达式的列表,这将导致所需的网络接口被忽略。以下配置将忽略“docker0”接口和以“veth”开头的所有接口。
spring:
cloud:
inetutils:
ignoredInterfaces:
- docer0
- veth.*
您还可以强制使用正则表达式列表中指定的网络地址:
spring:
cloud:
inetutils:
preferredNetworks:
-192.168
-10.0
您也可以强制仅使用站点本地地址。有关更多详细信息,请参阅Inet4Address.html.isSiteLocalAddress())是什么是站点本地地址
spring:
cloud:
inetutils:
useOnlySiteLocalInterfaces:true
Camden.SR6
Spring Cloud Config为分布式系统中的外部配置提供服务器和客户端支持。使用Config Server,您可以在所有环境中管理应用程序的外部属性。客户端和服务器映射的概念与Spring Environment和PropertySource抽象相同,因此它们与Spring应用程序非常契合,但可以与任何以任何语言运行的应用程序一起使用。随着应用程序通过从开发人员到测试和生产的部署流程,您可以管理这些环境之间的配置,并确定应用程序具有迁移时需要运行的一切。服务器存储后端的默认实现使用git,因此它轻松支持标签版本的配置环境,以及可用于管理内容的各种工具。可以轻松添加替代实现,并使用Spring配置将其插入
启动服务器:
$ cd spring-cloud-config-server
$ ../mvnw spring-boot:run
服务器是一个Spring引导应用程序,所以你可以从IDE运行它,(主类 ConfigServerApplication)。然后尝试一个客户端:
$ curl localhost:8888/foo/development
{"name":"development","label":"master","propertySources":[
{"name":"https://github.com/scratches/config-repo/foo-development.properties","source":{"bar":"spam"}},
{"name":"https://github.com/scratches/config-repo/foo.properties","source":{"foo":"bar"}}
]}
定位资源的默认策略是克隆git仓库(at spring.cloud.config.server.git.uri)并使用它来初始化一个mini SpringApplication。迷你应用程序 Environment用于枚举属性源并通过JSON端点发布。
HTTP服务具有以下格式的资源:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
其中“ 应用程序”是在常规Spring Boot应用程序中注入spring.config.name的 SpringApplication(即通常是“应用程序”),“配置文件”是活动配置文件(或逗号分隔的属性列表),“label”是可选的git标签(默认为“主”)。
Spring Cloud Config Server从git仓库(必须提供)中提取远程客户端的配置:
spring:
cloud:
config:
server:
git:
uri:https://github.com/spring-cloud-samples/config-repo
要在应用程序中使用这些功能,只需将其构建为依赖于spring-cloud-config-client的Spring Boot应用程序(例如,查看配置客户端或示例应用程序的测试用例)。添加依赖关系的最方便的方法是通过Spring Boot启动器 org.springframework.cloud:spring-cloud-starter-config。还有一个spring-cloud-starter-parentMaven用户的父pom和BOM()和用于Gradle和Spring CLI用户的Spring IO版本管理属性文件。示例Maven配置:
pom.xml
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.3.5.RELEASEversion>
<relativePath />
parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>Brixton.RELEASEversion>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-configartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
那么你可以创建一个标准的Spring Boot应用程序,就像这个简单的HTTP服务器:
@SpringBootApplication
@RestController
public class Application {
@RequestMapping(“/”)
public String home(){
return“Hello World!”;
}
public static void main(String [] args){
SpringApplication.run(Application.class,args);
}
}
当它运行它将从端口8888上的默认本地配置服务器接收外部配置,如果它正在运行。要修改启动行为,您可以使用bootstrap.properties(像application.properties应用程序上下文的引导阶段)来更改配置服务器的位置,例如
spring.cloud.config.uri:http://myconfigserver.com
引导属性将在/env端点中显示为高优先级属性源,例如:
$ curl localhost:8080 / env
{
“profiles”:[],
“configService:https://github.com/spring-cloud-samples/config-repo/bar.properties”:{“foo”:“bar”} ,
“servletContextInitParams”:{},
“systemProperties”:{...},
...
}
服务器为外部配置(名称值对或等效的YAML内容)提供了基于资源的HTTP。服务器可以使用@EnableConfigServer注释轻松嵌入到Spring引导应用 程序中。所以这个应用程序是一个配置服务器:
@SpringBootApplication
@EnableConfigServer
public class ConfigServer {
public static void main(String[] args) {
SpringApplication.run(ConfigServer.class, args);
}
}
像所有Spring Boot应用程序一样,它默认在端口8080上运行,但是您可以通过各种方式将其切换到常规端口8888。最简单的,也设置一个默认的配置库,是通过启动它spring.config.name=configserver(configserver.yml在Config Server jar中有一个)。另一个是使用你自己的application.properties,例如:
server.port: 8888
spring.cloud.config.server.git.uri: file://${user.home}/config-repo
NOTE 在Windows中,如果文件URL为绝对驱动器前缀,则需要额外的“/”,例如file:///${user.home}/config-repo。
TIP 以下是上面示例中创建git仓库的方法:
$ cd $HOME
$ mkdir config-repo
$ cd config-repo
$ git init .
$ echo info.foo: bar > application.properties
$ git add -A .
$ git commit -m "Add application.properties"
WARNING 使用本地文件系统进行git存储库仅用于测试。使用服务器在生产环境中托管配置库.
WARNING 果您只保留文本文件,则配置库的初始克隆将会快速有效。如果您开始存储二进制文件,尤其是较大的文件,则可能会遇到服务器中第一个配置请求和/或内存不足错误的延迟。
您要在哪里存储配置服务器的配置数据?管理这种行为的策略是 EnvironmentRepository服务Environment对象。这 Environment是Spring的一个浅层副本 Environment(包括propertySources作为主要功能)。该 Environment资源由三个变量参数化:
- {application} 在client边映射为”spring.application.name”
- {profile} 映射为”spring.profiles.active”
- {label} 服务器端的功能标记”版本”的配置文件.
存储库实现通常与Spring Boot应用程序一样,从“参数”等于“spring.config.name”加载配置文件{application},“spring.profiles.active”等于该{profiles}参数。配置文件的优先级规则也与常规启动应用程序相同:活动配置文件优先于默认配置,如果有多个配置文件,则最后一个配置文件(如向a添加条目Map)。
示例:客户端应用程序具有此bootstrap配置:
bootstrap.yml
spring:
application:
name: foo
profiles:
active: dev,mysql
如果存储库是基于文件的,则服务器将创建一个 Environmentfrom application.yml(在所有客户端之间共享)和 foo.yml(foo.yml优先)。如果YAML文件在其中具有指向Spring配置文件的文档,则应用较高优先级(按照列出的配置文件的顺序),并且如果存在特定于配置文件的YAML(或属性)文件,那么这些文件也应用的优先级高于默认值。较高的优先级转换为PropertySource前面列出的 Environment.(这些与在独立的Spring Boot应用程序中应用的规则相同.)
EnvironmentRepository使用Git后端的默认实现,这对于管理升级和物理环境以及审核更改非常方便.要更改存储库的位置,可以在Config Server中设置“spring.cloud.config.server.git.uri”配置属性(例如in application.yml)。如果您使用file:前缀进行设置,则应从本地存储库中运行,以便在没有服务器的情况下快速轻松地启动,但在这种情况下,服务器将直接在本地存储库上运行,而无需克隆(如果不是因为配置服务器从不对“远程”资源库进行更改。要扩展Config Server并使其高度可用,您需要将服务器的所有实例指向同一个存储库,所以只有一个共享文件系统才能工作。ssh:即使在这种情况下,最好使用共享文件系统存储库的协议,以便服务器可以将其克隆并使用本地工作副本作为缓存.
存储库{label}实现将HTTP资源的参数映射到git标签(提交ID,分支名称或标签)。如果git分支或标签名称包含斜杠(“/”),则应使用特殊字符串“(_)”指定HTTP URL中的标签,以避免与其他URL路径模糊。如果您使用像curl这样的命令行客户端(例如使用引号将其从shell中转出来),请小心URL中的方括号.
Spring Cloud Config Server支持的占位符一个Git仓库URl{application}和{profile}(和{label}如果你需要它,请记住,标签作为一个git标签反正使用)因此可以使用”每个程序一个repo”策略:
spring:
cloud:
config:
server:
git:
uri:https://github.com/myorg/{application}
或”一个profile一个repo”就和使用{profile}相同的策略
还可以通过应用程序和配置文件名称的路径匹配来支持更复杂的需求。路径格式是{application}/{profile}带有通配符的逗号分隔的名称列表(可能需要引用以通配符开头的模式)
例子:
spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
repos:
simple: https://github.com/simple/config-repo
special:
pattern: special*/dev*,*special*/dev*
uri: https://github.com/special/config-repo
local:
pattern: local*
uri: file:/home/configsvc/config-repo
如果{application}/{profile}不匹配任何路径,它将使用在“spring.cloud.config.server.git.uri”下定义的默认uri。在上述示例中,对于“简单”存储库,路径是simple/(即,它只匹配所有配置文件中名为“简单”的一个应用程序)。“本地”存储库将所有配置文件中以“local”开头的所有应用程序名称进行匹配(/后缀自动添加到任何没有配置文件匹配器的路径).
NOTE 在上述“简单”示例中使用的“单行”快捷方式只能在唯一要设置的属性为URI的情况下使用。如果您需要设置其他任何内容(凭据,模式等),则需要使用完整的表单。
pattern属性在repo中其实是一个数组,所以你可以使用YAML数组或者([0],[1]等后缀在配置文件中),组合绑定多个patterns.如果要运行具有多个配置文件的应用程序. 例如:
spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
repos:
development:
pattern:
- */development
- */staging
uri: https://github.com/development/config-repo
staging:
pattern:
- */qa
- */production
uri: https://github.com/staging/config-repo
NOTE Spring Cloud会猜测包含一个不会结束的配置文件的模式意味着您实际上希望匹配从此模式开始的配置文件列表(因此/staging是一个快捷方式 [“/staging”, “/staging,*”])。这是常见的,您需要在本地的“开发”配置文件中运行应用程序,但也可以远程运行“云”配置文件.
每个存储库还可以选择将配置文件存储在子目录中,搜索这些目录的模式可以指定为searchPaths。例如在顶层:
spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
searchPaths: foo,bar*
在此示例中,服务器搜索顶级和“foo /”子目录以及名称以“bar”开头的任何子目录中的配置文件。
默认情况下,首次请求配置时,服务器克隆远程存储库。服务器可以配置为在启动时克隆存储库。例如在顶层:
spring:
cloud:
config:
server:
git:
uri: https://git/common/config-repo.git
repos:
team-a:
pattern: team-a-*
cloneOnStart: true
uri: http://git/team-a/config-repo.git
team-b:
pattern: team-b-*
cloneOnStart: false
uri: http://git/team-b/config-repo.git
team-c:
pattern: team-c-*
uri: http://git/team-a/config-repo.git
在此示例中,服务器在启动之前克隆了team-a的config-repo,然后它接受任何请求。所有其他存储库将不被克隆,直到请求从存储库配置.
NOTE 在配置服务器启动时设置要克隆的存储库可以帮助在配置服务器启动时快速识别错误配置的源(例如,无效的存储库URI)。由于 cloneOnStart配置源未启用,配置服务器可能会以错误配置或无效的配置源成功启动,并且在应用程序从该配置源请求配置之前不会检测到错误.
要在远程存储库上使用HTTP基本身份验证,请分别添加“username”和“password”属性(不在URL中),例:
spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
username: trolley
password: strongpassword
如果您不使用HTTPS和用户凭据,当您将密钥存储在默认目录(~/.ssh)中并且uri指向SSH位置时,SSH也应该开箱即用,例如“ [email protected]:configuration / cloud-组态”。〜/ .ssh / known_hosts中的所有键都是“ssh-rsa”格式很重要。不支持新的“ecdsa-sha2-nistp256”格式。使用JGit访问存储库,因此您发现的任何文档都应适用。HTTPS代理设置可以~/.git/config通过系统属性(-Dhttps.proxyHost和-Dhttps.proxyPort)设置 或与其他任何JVM进程相同.
TIP 如果您不知道~/.git我们git config –global的目录在哪里操纵设置(例如git config –global http.sslVerify false).
Spring Cloud Config Server也支持占位符的搜索路径{application}和{profile}还有{label},例:
spring:
cloud:
config:
server:
git:
uri:https://github.com/spring-cloud-samples/config-repo
serachPaths:'{application}'
在资源库中搜索与目录(以及顶级)相同名称的文件。通配符在具有占位符的搜索路径中也是有效的(搜索中包含任何匹配的目录
如前所述,Spring Cloud Config Server克隆了远程git存储库,如果以某种方式本地副本变脏(例如,由操作系统进程更改文件夹内容),Spring Cloud Config Server无法从远程存储库更新本地副本。
要解决这个问题,有一个force-pull属性如果本地副本是脏的,将使Spring Cloud Config Server强制从远程存储库中拉取,例:
spring:
cloud:
config:
server:
git:
uri:https://github.com/spring-cloud-samples/config-repo
force-pull:true
如果你有多个仓库配置,你可以配置每一个force-pull像这样:
spring:
cloud:
config:
server:
git:
uri:https://git/common/config-repo.git
force-pull:true
repos:
team-a:
pattern:team-a-*
uri:http://git/team-a/config-repo.git
force-pull:true
team-b:
pattern:team-b-*
uri:http://git/team-b/config-repo.git
force-pull:true
team-c:
pattern:team-c-*
uri:http://git/team-a/config-repo.git
NOTE force-pull默认是false
WARNING 使用基于VCS的后端(git,svn)文件被检出或克隆到本地文件系统。默认情况下,它们放在系统临时目录中,前缀为config-repo-。在linux上,例如可能是/tmp/config-repo-。一些操作系统会定期清除临时目录。这可能会导致意外的行为,例如缺少属性。为避免此问题,请更改Config Server使用的目录,方法是设置spring.cloud.config.server.git.basedir或spring.cloud.config.server.svn.basedir不存在于系统临时结构中的目录
配置服务器中还有一个不使用Git的“本机”配置文件,只是从本地类路径或文件系统加载配置文件(您想要指向的任何静态URL“spring.cloud.config.server .native.searchLocations“)。要使用本机配置文件,只需使用“spring.profiles.active = native”启动Config Server
NOTE 记住使用file:文件资源的前缀(缺省没有前缀通常是类路径)。就像任何Spring引导配置一样,您可以嵌入 −style环境占位符,但请记住,Windows中的绝对路径需要额外的“/”,例如file:/// {user.home}/config-repo
WARNING searchLocations的默认值与本地Spring引导应用程序(so [classpath:/, classpath:/config, file:./, file:./config])相同。这不会将application.properties服务器暴露 给所有客户端,因为在发送到客户端之前,服务器中存在的任何属性源都将被删除.
TIP 文件系统后端对于快速入门和测试是非常好的。要在生产中使用它,您需要确保文件系统是可靠的,并在配置服务器的所有实例中共享。
搜索位置可以包含和{application}, {profile}和{label}。以这种方式,您可以隔离路径中的目录,并选择一个有用的策略(例如每个应用程序的子目录或每个配置文件的子目录)
如果您不在搜索位置使用占位符,则该存储库还会将{label}HTTP资源的参数附加到搜索路径上的后缀,因此,属性文件将从每个搜索位置和与标签名称相同的子目录加载(标记的属性在Spring环境中优先)。因此,没有占位符的默认行为与添加结尾的搜索位置/{label}/. For example `file:/tmp/config 相同file:/tmp/config,file:/tmp/config/{label}
Spring Cloud Config Server还支持Vault作为后端
Vault是安全访问秘密的工具,一个秘密是你想要严格控制访问的任何东西,如API密钥,密码,证书等等。Vault为任何秘密提供统一的界面,同时提供严格的访问控制和记录详细的审核日志
要启用配置服务器使用Vault后端,您必须使用配置vault文件运行配置服务器。例如在您的配置服务器中,application.properties 您可以添加spring.profiles.active=vault.
默认情况下,配置服务器将假定您的Vault服务器正在运行 http://127.0.0.1:8200.它也将假定后端的名称是secret关键application。所有这些默认值都可以在配置服务器中配置application.properties。以下是可配置的Vault
属性的表。所有属性前缀 spring.cloud.config.server.vault.
Name | Default Value |
---|---|
host | 127.0.0.1 |
port | 8200 |
scheme | http |
backend | secret |
defaultKey | application |
profileSeparator | , |
所有的配置都可以在org.springframework.cloud.config.server.environment.VaultEnvironmentRepository中找到
运行您的配置服务器,您可以向服务器发出HTTP请求,以从Vault后端检索值。为此,您将需要一个Vault服务器的令牌.
首先把一些数据放在你的Vault中。例如
$ vault write secret/application foo=bar baz=bam
$ vault write secret/myapp foo=myappsbar
现在,将HTTP请求发送给您的配置服务器以检索值
$ curl -X "GET" "http://localhost:8888/myapp/default" -H "X-Config-Token: yourtoken"
在提出上述request后,您应该会看到类似的response
{
"name":"myapp",
"profiles":[
"default"
],
"label":null,
"version":null,
"state":null,
"propertySources":[
{
"name":"vault:myapp",
"source":{
"foo":"myappsbar"
}
},
{
"name":"vault:application",
"source":{
"baz":"bam",
"foo":"bar"
}
}
]
}
使用Vault时,您可以为应用程序提供多个属性源。例如,假设您已将数据写入Vault中的以下路径
secret/myApp,dev
secret/myApp
secret/application,dev
secret/application
在secret/application写入的属性可以用于所有的用配置中心的程序,
名字叫myApp的会有在secret/myApp和secret/application的所有属性,当myApp有dev这个profile,那么上面四个所有的都可以使用
基于文件的仓库,像是git和svn还有原生的,名字是application*的资源会在所有客户端之间共享(像application.properties,application.yml,application-*.properties等).你可以使用这些名字来配置全局的默认配置,并根据需要将其覆盖应用程序特定的文件.
TIP 使用”native”profile,(本地文件后端),建议您使用不属于服务器自身配置的显式搜索位置。否则,application* 默认搜索位置中的资源将被删除,因为它们是服务器的一部分
使用Vault作为后端时,您可以通过将配置放入其中来与所有应用程序共享配置 html5/application。例如,如果您运行此Vault命令
$ vault write secret/application foo=bar baz=bam
所有的使用配置中心的应用将会获得foo和baz属性
在某些情况下,您可能希望从多个环境存储库中提取配置数据。为此,只需在配置服务器的应用程序属性或YAML文件中启用多个配置文件即可。例如,如果您要从Git存储库以及SVN存储库中提取配置数据,那么您将为配置服务器设置以下属性.
spring:
profiles:
active:git,svn
cloud:
config:
server:
svn:
uri:file:///path/to/svn/repo
order:2
git:
uri:file:///path/to/git/repo
order:1
除了指定URI的每个repo之外,还可以指定一个order属性。该order属性允许您指定所有存储库的优先级顺序。order属性的数值越低,优先级越高。存储库的优先顺序将有助于解决包含相同属性的值的存储库之间的任何潜在冲突。
NOTE 环境仓库检索值时的任何类型的故障将导致整个复合环境的故障。
NOTE 当使用复合环境时,重要的是所有repos都包含相同的标签。如果您有类似于上述的环境,并且使用master标签请求配置数据,但SVN repo不包含称为master整个请求的分支将失败。
EnvironmentRepository除了使用Spring Cloud的一个环境存储库之外,还可以提供自己的bean作为复合环境的一部分。为此,您的bean必须实现该EnvironmentRepository接口。如果要控制EnvironmentRepository复合环境中自定义的优先级,您还应该实现该Ordered接口并覆盖该 getOrdered方法。如果你不实现Ordered接口,那么你 EnvironmentRepository将被给予最低优先级。
配置中心具有”覆盖”功能,允许操作人员向所有应用提供配置属性,使用Spring Boot hooks的应用不会意外的改变,要声明覆盖,只需添加 name-value 对的映射 spring.cloud.config.server.overrides.
例如:
spring:
cloud:
config:
server:
overrides:
foo: bar
将导致配置客户端的所有应用程序foo=bar 独立于自己的配置进行读取。(当然,应用程序可以以任何其他方式使用Config Server中的数据,因此覆盖不可强制执行,但如果它们是Spring Cloud Config客户端,则它们会提供有用的默认行为.)
TIP 通过使用反斜杠(“\”)来转义“”或“{”,例如\${app.foo:bar}解析为“bar”,除非应用程序正常,Spring环境占位符“ {}”可以转义(并在客户端上解决)提供自己的“app.foo”。请注意,在YAML中,您不需要转义反斜杠本身,而是在您执行的属性文件中配置服务器上的覆盖
您可以将客户端所有的覆盖的优先级更改为默认值,允许应用程序通过spring.cloud.config.overrideNone=true在远程存储库中设置标志(默认为false),在环境变量或系统属性中提供自己的值.
配置中心附带运行状况指示器,检查配置EnviromentRepository是否正常,默认情况下,它对一个应用要求EnvironmentRepository名叫app,默认的profile和默认的label通过EnvironmentRepository的实现来提供
您可以配置运行状况指示器以检查更多应用程序以及自定义配置文件和自定义标签,例如:
spring:
cloud:
config:
server:
health:
repositories:
myservice:
label:mylabel
myservice-dev:
name:myservice
profiles:development
你可以通过设置来禁止运行状况指示器spring.cloud.config.server.health.enabled=false
你可以用任何有意义的方式(物理安全到OAuth2令牌)来保护你的配置中心,而Spring Security和Spring Boot可以轻松做任何事情
要使用默认的Spring Boot配置的HTTP Basic安全,只需要在类路径中包括Spring Security(例如spring-boot-starter-security),默认的用户名为”user”和一个随机生成的密码,这在实践中没什么用,因此,我们建议你配置你的密码(可以通过security.user.password)并且加密它.
IMPORTANT 先决条件:要使用加密和解密功能,您需要在JVM中安装全面的JCE(默认情况下不存在).您可以从Oracle下载“Java加密扩展(JCE)无限强度管理策略文件”,并按照安装说明(实际上将JRE lib / security目录中的2个策略文件替换为您下载的文件)
如果远程属性源包含加密内容(以{cipher}开头的值),则在通过HTTP发送给客户端之前,将被解密,这种设置的主要优点是,当它们”静止”时,属性值不必是纯文本(例如在git仓库中).如果值无法解密,则从属性源中删除该值,并添加相同的key的附加属性,但是以”invalid开头,和”not applicable”的值.这主要是为了防止cipher被用作密码并以外泄露.
如果您正在为配置客户端应用程序设置远程配置存储库,可能会包含application.yml类似的内容
例如:
application.yml
spring:
datasource:
username:dbuser
password:'{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSA'
.properties文件中的加密值不能用引号括起来,否则不会解密该值
application.properties
spring.datasource.username: dbuser
spring.datasource.password:{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ
您可以安全地将此纯文本推送到共享git存储库,并且保密密码
服务器还暴露/encrypt和/decrypt端点(假设这些将被保护并且只能由授权代理访问)。如果您正在编辑远程配置文件,可以使用配置中心通过POST /encrypt端点来加密值
例如:
$ curl localhost:8888 / encrypt -d mysecret
682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
逆操作也可以通过/decrypt(如果服务器配置了对称密钥或全密钥对):
$ curl localhost:8888/decrypt -d 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
mysecret
TIP 如果您使用curl进行测试,则使用 –data-urlencode(而不是-d)或设置显式Content-Type: text/plain来确保在有特殊字符(’+’特别棘手)时curl对数据进行正确编码.
在提交并将其推送到远程可能不安全的存储之前添加前缀{cipher}前缀,然后再放进YAML或属性文件.
该/encrypt和/decrypt端点也均接受该形式的路径/*/{name}/{profiles},当客户端要求主环境资源时可用于控制每个应用程序(名称)和配置文件加密
NOTE 要以这种细粒度的方式控制密码,您还必须提供一种@Bean类型TextEncryptorLocator,可以根据名称和配置文件创建不同的加密器。默认提供的不会这样做(所有加密使用相同的密钥)。
spring 命令行客户端(Spring Cloud CLI 扩展)也可以用于加密和解密
例:
$ spring encrypt mysecret --key foo
682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
$ spring decrypt --key foo 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
mysecret
要在文件中使用密钥(例如用于RSA公钥的加密),使用”@”,并提供文件路径
例如:
$ spring encrypt mysecret --key @${HOME}/.ssh/id_rsa.pub
AQAjPgt3eFZQXwt8tsHAVv/QHiY5sI2dRcR+...
关键参数是强制性的(尽管只有一个–前缀)
配置中心可以使用对称密钥或者非对称密钥(RSA),非对称性的在安全性方面是优越的,但是使用对称密钥往往更方便,因为它只配置一个属性值.
要配置一个对称密钥,你只需要设置encrypt.key一个秘密字符串(或使用环境变量ENCRYPT_KEY,将其保留在纯文本配置文件之外).
要配置非对称密钥,你可以将密钥设置为PEM编码的文本值(在encrypt.key),或者通过一个密钥库(例如keytool创建的,是JDK自带的),密钥库存储属性是encrypt.keyStore.,这个等同于
- location (资源位置)
- password (用来打开密钥库)
- alias (置顶哪个在库中的密钥被使用)
使用公钥进行加密,需要私钥进行解密。因此,原则上您只能在服务器中配置公钥,如果您只想进行加密(并准备使用私钥本地解密值)。实际上,您可能不想这样做,因为它围绕所有客户端传播密钥管理流程,而不是将其集中在服务器中。另一方面,如果您的配置服务器真的相对不安全,并且只有少数客户端需要加密的属性,这是一个有用的选项.
要创建一个密钥库进行测试,您可以执行以下操作:
$ keytool -genkeypair -alias mytestkey -keyalg RSA \
-dname "CN=Web Server,OU=Unit,O=Organization,L=City,S=State,C=US" \
-keypass changeme -keystore server.jks -storepass letmein
将server.jks文件放在类路径中,然后在你的application.yml的配置中心
中:
encrypt;
keyStore:
location:classpath:/server.jks
password:letmein
alias:mytestkey
secret: changeme
除了加密属性值的{cipher}前缀之外,配置中心还会寻找{name:value}前缀(0个或多个)在cipher文本开始之前,这些key通过TextEcrypttoLocator 可以做任何逻辑需要找到一个TextEncryptor cipher.如果你配置了密钥库(encrypt.keystore.location)默认的定位器将会在仓库中通过提供的”key”前缀查找kyes 例如:
foo:
bar: `{cipher}{key:testkey}...`
定位器将寻找一个叫做”testkey”的键,也可以通过{secret:…}前缀来提供一个秘密,但是如果它不是默认的使用密钥库密码(这是您在构建密钥库时获得的密码,而不指定密码),如果你这样做提供一个secret,建议你可以使用自定义的SecretLocator来加密
如果密钥只用于加密几个字节的配置数据(即它们没有在其他地方使用),则密码转换几乎不是必需的,但是如果存在安全漏洞,有时您可能需要更改密钥实例。在这种情况下,所有客户端都需要更改其源配置文件(例如,以git格式),并{key:…}在所有密码中使用新的前缀,事先检查配置服务器密钥库中的密钥别名是否可用.
TIP 如果要让Config Server处理所有加密以及解密,{name:value}也可以 将前缀添加到明文发布到/encrypt端点。
有时您希望客户端在本地解密配置,而不是在服务器中进行配置。在这种情况下,您仍然可以拥有/加密和/解密端点(如果您提供encrypt.* 配置来定位密钥),但是您需要明确地关闭使用传出属性的解密 spring.cloud.config.server.encrypt.enabled=false。如果您不关心端点,那么如果您既不配置密钥也不配置使能的标志,则应该起作用
来自环境端点的默认JSON格式是适用于Spring应用程序的消费,因为它直接映射到 Environment抽象上。如果您喜欢,可以通过向资源路径(“.yml”,“.yaml”或“.properties”)添加后缀来使用与YAML或Java属性相同的数据。这对于不关心JSON端点的结构的应用程序的消费或其提供的额外的元数据可能是有用的,例如,不使用Spring的应用程序可能会受益于此方法的简单性。
YAML和properties表示有一个额外的标志(以boolean类型查询参数的形式提供resolvePlaceholders),用于表示源文档中标准Spring ${…}窗体中的占位符应在渲染前尽可能在输出中解析。这对于不了解Spring占位符约定的消费者来说是一个有用的功能.
NOTE 使用YAML或properties格式存在局限性,主要是与元数据的丢失有关。JSON被构造为属性源的有序列表,例如,名称与源相关联。即使源的起源具有多个源,并且原始源文件的名称丢失,YAML和properties表也合并成一个映射。YAML表示不一定是后台存储库中YAML源的忠实表示:它是由平面属性源的列表构建的,并且必须对键的形式进行假设.
Environment您的应用程序可能需要通用的纯文本配置文件,而不是使用抽象(或YAML或属性格式中的其他替代表示形式).配置服务器通过附加端点提供这些端口,/{name}/{profile}/{label}/{path} 其中“name”,“profile”和“label”的含义与常规环境端点相同,但“path”是文件名(例如log.xml).此端点的源文件位于与环境端点相同的方式:与properties或YAML文件相同的搜索路径,而不是聚合所有匹配的资源,只返回匹配的第一个.
找到资源后,根据application name,profile和label,被激活的Environment中以正常的格式(${…})来处理占位符.以这种方式,资源端点与环境端点紧密集成。例如,如果您有一个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像这样:
server{
listen 80;
server_name example.com;
}
还有 /foo/development/master/nginx.conf 像这样:
server{
listen 80;
server_name develop.com;
}
NOTE 就像环境配置的源文件一样,“配置文件”用于解析文件名,因此如果您想要一个特定于配置文件的文件,那么//development//logback.xml将被一个名为logback-development.xml(优先于logback.xml)的文件解析.
配置服务器最好作为独立应用程序运行,但如果需要,可以将其嵌入到另一个应用程序中。只需使用 @EnableConfigServer注解。在这种情况下可以使用的可选属性是spring.cloud.config.server.bootstrap是指示服务器应该从其自己的远程仓库配置自己的标志。该标志默认关闭,因为它可能会延迟启动,但是当嵌入在另一个应用程序中时,与任何其他应用程序初始化相同是有意义的.
NOTE 这是显而易见的,但请记住,如果您使用bootstrap标志,配置服务器将需要在bootstrap.yml配置其名称和存储库URI
想要更改服务端点的定位,您可以(可选)spring.cloud.config.server.prefix,例如“/ config”,来提供前缀下的资源。前缀应该开始但不以“/”结尾。它在Config Server中应该是@RequestMappings(即在Spring Boot下是前缀server.servletPath和 server.contextPath)。
如果您想直接从后端存储库(而不是从配置服务器)读取应用程序的配置,这基本上是一个没有端点的内嵌的配置服务器。如果您不使用@EnableConfigServer 注解(只设置spring.cloud.config.server.bootstrap=true),您可以完全关闭端点。
许多代码仓库提供者(例如Github,Gitlab或Bitbucket)将通过webhook通知您存储库中的更改。您可以通过提供商的用户界面将webhook配置为URL和一组感兴趣的事件。例如, Github 将使用包含提交列表的JSON主体和“X-Github-Event”等于“push”的头文件发送到webhook。如果在spring-cloud-config-monitor库中添加依赖关系并在Config Server中激活Spring Cloud Bus,则会启用“/ monitor”端点。
当启动Webhook时,配置服务器将发送一个 RefreshRemoteApplicationEvent针对他认为可能已经更改的应用程序。变更检测可以进行策略化,但默认情况下,它只是查找与应用程序名称匹配文件的更改(例如,“foo.properties”针对“foo”应用程序,“application.properties”针对所有应用程序) 。如果要覆盖行为的策略是PropertyPathNotificationExtractor,这个 接受请求头和主体作为参数,并返回更改的文件路径列表。
默认配置与Github,Gitlab或Bitbucket配合使用。除了Github,Gitlab或Bitbucket的JSON通知之外,你可以通过form-encoded的参数path={name}用POST方式发送到”/monitor”来触发改变通知。这将广播到匹配“{name}”路径的应用程序(可以包含通配符)。
NOTE RefreshRemoteApplicationEvent仅仅会在配置中心和客户端应用激活spring-cloud-bus的情况下传输
NOTE 默认的配置也会发现本地的git仓库的变化(在这种情况下webhook是没有用的,但是一旦编辑配置文件,将会广播一次刷新)
Spring Boot应用程序可以立即利用Spring Config Server(或应用程序开发人员提供的其他外部属性源),并且还可以选择与Environment更改事件相关的一些其他有用功能。
这是在类路径中具有Spring Cloud Config Client的任何应用程序的默认行为。当配置客户端启动时,它将绑定到配置服务器(通过bootstrap配置属性spring.cloud.config.uri),并且Spring Environment使用远程属性源初始化 。
最终的结果是,所有想要使用配置服务器的客户端应用程序都需要一个bootstrap.yml(或者一个环境变量)配置服务器地址spring.cloud.config.uri(默认为“http:// localhost:8888”).
如果您正在使用“DiscoveryClient”实现,例如Spring Cloud Netflix和Eureka Service Discovery或Spring Cloud Consul(Spring Cloud Zookeeper还不支持此功能),那么您可以让Config Server注册Discovery Discovery,但在默认的“配置优先”模式下,客户端将无法利用注册。
如果您希望使用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)在客户端上进行更改。
discovery client实现都支持某种元数据映射(例如Eureka的 eureka.instance.metadataMap)。可能需要在其服务注册元数据中配置Config Server的一些其他属性,以便客户端可以正确连接。如果使用HTTP Basic安全配置服务器,则可以将凭据配置为”username”和”password”。并且如果配置服务器具有上下文路径,您可以设置“configPath”。例如,对于作为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到类路径。默认行为是重试6次,初始间隔为1000ms,指数乘数为1.1,用于后续backoffs。您可以使用spring.cloud.config.retry.*配置属性配置这些属性(和其他)。
TIP 要完全控制重试,添加一个id为“configServerRetryInterceptor” @Bean的类型 RetryOperationsInterceptor。Spring Retry有一个RetryInterceptorBuilder可以轻松创建一个。
配置服务从/{name}/{profile}/{label}提供property sources,客户端应用程序中的默认绑定的属性源
“name”= ${spring.application.name}
“profile”= ${spring.profiles.active}(实际上是Environment.getActiveProfiles())
“label”=“master”
所有这些都可以通过设置spring.cloud.config.* (其中*是“name”,“profile”和“label”)覆盖。“label”可用于回滚到以前版本的配置,使用默认的Config Server实现,它可以是git label ,分支名称或commit id。label也可以以逗号分隔的列表形式提供,在这种情况下,列表中的项目会逐个尝试,直到成功。当在特征分支上工作时,例如,当您可能希望将配置标签与分支对齐,但使其成为可选(例如spring.cloud.config.label=myfeature,develop)时,这可能非常有用.
如果您在服务器上使用HTTP基本安全性,那么客户端只需要知道密码(如果不是默认用户名)。您可以通过配置服务器URI,或通过单独的用户名和密码属性,例如
bootstrap.yml
spring:
cloud:
config:
uri: https://user:secret@myconfig.mycompany.com
或者
bootstrap.yml
spring:
cloud:
config:
uri: https://myconfig.mycompany.com
username: user
password: secret
the spring.cloud.config.password和spring.cloud.config.username values将覆盖URI中提供的任何内容。
如果您在Cloud Foundry部署应用程序,则提供密码的最佳方式是通过服务凭证(例如URI),因为它甚至不需要在配置文件中。在Cloud Foundry上为本地工作的用户提供的服务的一个例子,名为“configserver”:
bootstrap.yml
spring:
cloud:
config:
uri: ${vcap.services.configserver.credentials.uri:http://user:password@localhost:8888}
如果您使用安全的另一种形式,你可能需要提供 RestTemplate的ConfigServicePropertySourceLocator(例如在bootstrpa上下文中注入一个)。
Config Client提供一个尝试从Config Server加载配置的Spring Boot 健康指示器。健康指示器可以通过设置来禁用health.config.enabled=false。由于性能原因,响应也被缓存。默认缓存生存时间为5分钟。要更改该值,请设置health.config.time-to-live属性(以毫秒为单位)。
在某些情况下,您可能需要从客户端自定义对配置服务器的请求。通常,这涉及到传递特殊的Authorization头来验证对服务器的请求。要提供自定义,RestTemplate请按照以下步骤操作。
设置spring.cloud.config.enabled=false为禁用现有的配置服务器属性源。
创建一个具有实现的新配置bean PropertySourceLocator。
CustomConfigServiceBootstrapConfiguration.java
@Configuration
public class CustomConfigServiceBootstrapConfiguration {
@Bean
public ConfigClientProperties configClientProperties() {
ConfigClientProperties client = new ConfigClientProperties(this.environment);
client.setEnabled(false);
return client;
}
@Bean
public ConfigServicePropertySourceLocator configServicePropertySourceLocator() {
ConfigClientProperties clientProperties = configClientProperties();
ConfigServicePropertySourceLocator configServicePropertySourceLocator = new ConfigServicePropertySourceLocator(clientProperties);
configServicePropertySourceLocator.setRestTemplate(customRestTemplate(clientProperties));
return configServicePropertySourceLocator;
}
}
在resources/META-INF创建一个调用的文件 spring.factories并指定您的自定义配置。
spring.factorties
org.springframework.cloud.bootstrap.BootstrapConfiguration = com.my.config.client.CustomConfigServiceBootstrapConfiguration
当使用Vault作为配置服务器的后端时,客户端将需要为服务器提供一个令牌,用来从Vault中检索值。该令牌可以通过设置在客户端 bootstrap.yml中提供spring.cloud.config.token
bootstrap.yml
spring:
cloud:
config:
token:YourVaultToken
Vault 支持将密钥嵌套保存在Vault中,例如:
echo -n '{"appA":{"secret":"appAsecret","bar":"baz"}}' | vault write secret/myapp -
此命令将将一个JSON对象写入您的Vault。要在Spring中访问这些值,您将使用传统的点(.)注解。例如
@Value("${appA.secret}")
String name = "World";
上面的代码将设置name变量appAsecret