Spring Cloud Config
基础认识(Spring Cloud Config 2.2.2.RELEASE) :Spring Cloud Config为分布式系统中的外部配置提供服务器和客户端支持。使用Config Server,可以管理应用程序中,所有环境的外部配置。客户端和服务器上的概念与Spring Environment和PropertySource抽象相同,所以,它们与Spring应用程序非常合适,可以与以任何语言运行的应用程序一起使用。随着程序,通过部署管道===>从开发到测试和生产的流程,你可以管理在这些环境的配置,并且确保应用程序在迁移时拥有运行所需的一切。服务器存储后端的默认实现使用git,因此它轻松支持标签版本的配置环境,还可以使用各种工具来管理内容。可以轻松添加替代实现,并使用Spring配置将其插入。它可以轻松添加替代实现,并用Spring配置将其插入。
快速开始
- 启动服务器:
$ cd spring-cloud-config-server
$ …/mvnw spring-boot:run
这个服务器是一个Spring Boot应用程序,因此如果您愿意,可以从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仓库(在spring.cloud.config.server.git.uri),并使用它来初始化一个迷你SpringApplication。迷你应用程序的Environment用于枚举属性源并通过JSON端点发布。
HTTP服务具有以下格式的资源:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.yml
/{label}/{application}-{profile}.properties
其中application作为SpringApplication中的spring.config.name注入(通常是常规spring boot应用程序中的应用程序),profile是活动的profile(或以逗号分隔的属性列表),label是可选的git标签(默认为master)
Spring Cloud Config服务器从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。Maven用户可以使用Maven的父pom和BOM(spring-cloud-starter-parent),还有用Gradle和Spring CLI用户的Spring IO版本管理属性文件。示例Maven配置:
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>{spring-boot-docs-version}</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>{spring-cloud-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<!-- repositories also needed for snapshots and milestones -->
接下来你可以创建一个标准的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);
}
}
当这个HTTP服务器运行时,它从端口8888上的默认本地配置服务器(如果它正在运行)中获取外部配置。如果要修改启动行为,您可以使用bootstrap.properties(类似于application.properties,但适用于应用程序上下文的引导阶段)更改配置服务器的位置,例如
spring.cloud.config.uri: http://myconfigserver.com
默认情况下,如果未设置应用程序名称,则将使用应用程序。要修改名称,可以将以下属性添加到bootstrap.properties文件中:
引导属性将在/env端点中显示为高优先级属性源,例如
spring.application.name: myapp
一个引导程序的属性在/env端点中显示为高优先级属性源,如以下示例所示。
$ curl localhost:8080/env
{
"profiles":[],
"configService:https://github.com/spring-cloud-samples/config-repo/bar.properties":{"foo":"bar"},
"servletContextInitParams":{},
"systemProperties":{...},
...
}
名为:configService: <远程存储库的URL>/<文件名> 其中一个键为foo,值为bar的属性, 是最高优先级。
😐 注意:属性源名称中的URL是git存储库的,而不是配置服务器的URL。
Spring Cloud Config服务器
服务器为外部配置(名称值对或等效的YAML内容)提供了基于资源的HTTP。服务器可以使用@EnableConfigServer注释轻松嵌入到Spring Boot应用程序中。所以这个应用程序是一个配置服务器:
ConfigServer.java
@SpringBootApplication
@EnableConfigServer
public class ConfigServer {
public static void main(String[] args) {
SpringApplication.run(ConfigServer.class, args);
}
}
像所有默认情况下在端口8080上运行的所有Spring Boot应用程序一样,但您可以通过各种方式将其切换到常规端口8888。最简单的设置默认配置存储库是通过使用spring.config.name=configserver启动(在Config Server jar中有一个configserver.yml),也可以使用你自己的application.properties,例如:
application.properties
server.port: 8888
spring.cloud.config.server.git.uri: file://${user.home}/config-repo
其中${user.home}/config-repo是包含YAML和属性文件的git仓库。
| 注意 | 在Windows中,如果文件URL为绝对带有驱动器前缀,例如file:///${user.home}/config-repo,则需要额外的“/”。 |
提示:以下清单显示了在前面的示例中创建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”
警告:将本地文件系统用于git存储库仅用于测试。您应该使用服务器在生产环境中托管配置存储库。
警告:如果仅将文本文件保留在其中,则配置存储库的初始克隆可以快速有效。如果存储二进制文件(尤其是大文件),则可能会在首次配置请求时遇到延迟,或者在服务器中遇到内存不足错误。
环境库
您要在哪里存储配置服务器的配置数据?管理此行为的策略是EnvironmentRepository,服务于Environment对象。这个Environment是Spring Environment(包括propertySources作为主要功能)的域的浅层副本。Environment资源由三个变量参数化:
-
{application}映射到客户端的“spring.application.name”;
-
{profile}映射到客户端上的“spring.profiles.active”(逗号分隔列表); 和
-
{label}这是一个服务器端功能,标记“版本”的一组配置文件。
存储库实现通常表现得像一个Spring Boot应用程序从“spring.config.name”等于{application}参数加载配置文件,“spring.profiles.active”等于{profiles}参数。配置文件的优先级规则也与常规启动应用程序中的相同:活动配置文件优先于默认配置,如果存在多个配置文件,则最后一个配置文件(例如向Map添加条目))。
示例:客户端应用程序具有此引导配置:
bootstrap.yml
spring:
application:
name: foo
profiles:
active: dev,mysql
像往常一样使用Spring Boot应用程序,这些属性也可以设置为环境变量或命令行参数)。
如果存储库是基于文件的,则服务器将从application.yml创建Environment(在所有客户端之间共享),foo.yml(以foo.yml优先))。如果YAML文件在其中具有指向Spring配置文件的文档,则应用较高优先级(按照列出的配置文件的顺序),并且如果存在特定于配置文件的YAML(或属性)文件,那么这些文件也应用的优先级高于默认值。较高优先级转换为Environment之前列出的PropertySource。(这些规则与独立的Spring Boot应用程序相同。)
Git后端
EnvironmentRepository的默认实现使用Git后端,这对于管理升级和物理环境以及审核更改非常方便。要更改存储库的位置,可以在Config Server中设置“spring.cloud.config.server.git.uri”配置属性(例如application.yml)。如果您使用file:前缀进行设置,则应从本地存储库中运行,以便在没有服务器的情况下快速方便地启动,但在这种情况下,服务器将直接在本地存储库中进行操作,而不会克隆它如果它不是裸机,因为配置服务器永远不会更改“远程”资源库)。要扩展Config Server并使其高度可用,您需要将服务器的所有实例指向同一个存储库,因此只有共享文件系统才能正常工作。即使在这种情况下,最好使用共享文件系统存储库的ssh:协议,以便服务器可以将其克隆并使用本地工作副本作为缓存。
该存储库实现将HTTP资源的{label}参数映射到git标签(提交ID,分支名称或标签)。如果git分支或标签名称包含斜杠(“/”),则应使用特殊字符串“( )”指定HTTP URL中的标签,以避免与其他URL路径模糊。例如,如果标签是foo/bar,则替换斜杠将导致类似于foo( )bar的标签。如果您使用像curl这样的命令行客户端(例如使用引号将其从shell中转出来),请小心URL中的方括号。
Git URI中的占位符
Spring Cloud Config服务器支持一个Git仓库URL,其中包含{application}和{profile}(以及{label})的占位符,如果需要,请记住,标签应用为git标签)。因此,您可以使用(例如)轻松支持“每个应用程序的一个repo”策略:
spring:
cloud:
config:
server:
git:
uri: https://github.com/myorg/{application}
或使用类似模式“一个存储库一个配置文件”的策略,但需要使用{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”开头的所有应用程序名称匹配(将/*后缀自动添加到任何没有配置文件匹配器的模式)。
注意:
在上述“简单”示例中使用的“单行”快捷方式只能在唯一要设置的属性为URI的情况下使用。如果您需要设置其他任何内容(凭据,模式等),则需要使用完整的表单。
repo中的pattern属性实际上是一个数组,因此您可以使用属性文件中的YAML数组(或[0],[1]等后缀)绑定到多个模式。如果要运行具有多个配置文件的应用程序,则可能需要执行此操作。例:
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
注意
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,然后它接受任何请求。所有其他存储库将不被克隆,直到请求从存储库配置。
注意
在配置服务器启动时设置要克隆的存储库可以帮助在配置服务器启动时快速识别错误配置的源(例如,无效的存储库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也应该开箱即用,例如“ git@github.com:配置/云配置”。重要的是,Git服务器的条目存在于~/.ssh/known_hosts文件中,并且格式为ssh-rsa。不支持其他格式(如ecdsa-sha2-nistp256)。为了避免意外,您应该确保Git服务器的known_hosts文件中只有一个条目存在,并且与您提供给配置服务器的URL匹配。如果您在URL中使用了一个主机名,那么您希望在known_hosts文件中具有该主机名,而不是IP。使用JGit访问存储库,因此您发现的任何文档都应适用。HTTPS代理设置可以~/.git/config设置,也可以通过系统属性(-Dhttps.proxyHost和-Dhttps.proxyPort)与任何其他JVM进程相同。
提示
如果您不知道~/.git目录在何处使用git config --global操纵设置(例如git config --global http.sslVerify false)。
使用AWS CodeCommit进行认证
AWS CodeCommit认证也可以完成。当从命令行使用Git时,AWS CodeCommit使用身份验证助手。该帮助器不与JGit库一起使用,因此如果Git URI与AWS CodeCommit模式匹配,则将创建用于AWS CodeCommit的JGit CredentialProvider。AWS CodeCommit URI始终看起来像 https://git-codecommit.$ {AWS_REGION} .amazonaws.com / $ {repopath}。
如果您使用AWS CodeCommit URI提供用户名和密码,那么这些URI必须 是用于访问存储库的AWS accessKeyId和 secretAccessKey。如果不指定用户名和密码,则将使用AWS默认凭据提供程序链检索accessKeyId和secretAccessKey 。
如果您的Git URI与CodeCommit URI模式(上述)匹配,则必须在用户名和密码或默认凭据提供程序链支持的某个位置中提供有效的AWS凭据。AWS EC2实例可以使用EC2实例的 IAM角色。
注意:aws-java-sdk-core jar是一个可选的依赖关系。如果aws-java-sdk-core jar不在您的类路径上,则无论git服务器URI如何,都将不会创建AWS代码提交凭据提供程序。
Git搜索路径中的占位符
Spring Cloud Config服务器还支持{application}和{profile}(以及{label}(如果需要))占位符的搜索路径。例:
spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
searchPaths: '{application}'
在资源库中搜索与目录(以及顶级)相同名称的文件。通配符在具有占位符的搜索路径中也是有效的(搜索中包含任何匹配的目录)。
强力拉取Git存储库
如前所述Spring Cloud Config服务器克隆远程git存储库,如果某种方式本地副本已经改变(例如,由操作系统进程更改文件夹内容),则Spring Cloud Config服务器无法从远程存储库更新本地副本。
要解决这个问题,有一个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属性的默认值为false。
Spring Cloud Config客户端
一个Spring Boot应用程序可以立即利用Spring Config Server(或应用程序开发人员提供的其他外部属性源),并且还将获取与Environment更改事件相关的一些其他有用功能。
配置第一引导
这是在类路径中具有Spring Cloud Config Client的任何应用程序的默认行为。当配置客户端启动时,它将通过配置服务器(通过引导配置属性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找到Config Server,可以通过设置spring.cloud.config.discovery.enabled=true(默认为“false”)来实现。最终的结果是客户端应用程序都需要具有适当的发现配置的bootstrap.yml(或环境变量)。例如,使用Spring Cloud Netflix,您需要定义Eureka服务器地址,例如eureka.client.serviceUrl.defaultZone。使用此选项的价格是启动时额外的网络往返,以定位服务注册。好处是配置服务器可以更改其坐标,只要发现服务是一个固定点。默认的服务标识是“configserver”,但是您可以使用spring.cloud.config.discovery.serviceId在客户端上进行更改(在服务器上可以通过设置spring.application.name以通常方式更改服务。
发现客户端实现都支持某种元数据映射(例如,对于Eureka,我们有eureka.instance.metadataMap)。可能需要在其服务注册元数据中配置Config Server的一些其他属性,以便客户端可以正确连接。如果使用HTTP Basic安全配置服务器,则可以将凭据配置为“用户名”和“密码”。并且如果配置服务器具有上下文路径,您可以设置“configPath”。例如,对于作为Eureka客户端的配置服务器:
bootstrap.yml
eureka:
instance:
...
metadataMap:
user: osufhalskjrtl
password: lviuhlszvaorhvlo5847
configPath: /config
配置客户端快速失败
在某些情况下,如果服务无法连接到配置服务器,则可能希望启动服务失败。如果这是所需的行为,请设置引导配置属性spring.cloud.config.failFast=true,客户端将以异常停止。
配置客户端重试
如果您希望配置服务器在您的应用程序启动时可能偶尔不可用,您可以要求它在发生故障后继续尝试。首先,您需要设置spring.cloud.config.failFast=true,然后您需要将spring-retry和spring-boot-starter-aop添加到您的类路径中。默认行为是重试6次,初始退避间隔为1000ms,指数乘数为1.1,用于后续退避。您可以使用spring.cloud.config.retry.*配置属性配置这些属性(和其他)。
提示
要完全控制重试,请使用id“configServerRetryInterceptor”添加RetryOperationsInterceptor类型的@Bean。Spring Retry有一个RetryInterceptorBuilder,可以轻松创建一个。
查找远程配置资源
配置服务从/{name}/{profile}/{label}提供属性源,客户端应用程序中的默认绑定
-
“name”= ${spring.application.name}
-
“profile”= ${spring.profiles.active}(实际上是Environment.getActiveProfiles())
-
“label”=“master”
所有这些都可以通过设置spring.cloud.config. (其中 是“name”,“profile”或“label”)来覆盖。“标签”可用于回滚到以前版本的配置; 使用默认的Config Server实现,它可以是git标签,分支名称或提交ID。标签也可以以逗号分隔的列表形式提供,在这种情况下,列表中的项目会逐个尝试,直到成功。例如,当您可能希望将配置标签与您的分支对齐,但使其成为可选(例如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
spring.cloud.config.password和spring.cloud.config.username值覆盖URI中提供的任何内容。
如果您在Cloud Foundry部署应用程序,则提供密码的最佳方式是通过服务凭证(例如URI),因为它甚至不需要在配置文件中。在Cloud Foundry上为本地工作的用户提供的服务的一个例子,名为“configserver”:
bootstrap.yml
spring:
cloud:
config:
uri: ${vcap.services.configserver.credentials.uri:http://user:password@localhost:8888}
如果您使用另一种形式的安全性,则可能需要向ConfigServicePropertySourceLocator提供RestTemplate(例如,通过在引导上下文中获取它并注入一个)。ConfigServicePropertySourceLocator 提供{249 /}(例如通过在引导上下文中获取它并注入)。
健康指标
配置客户端提供尝试从配置服务器加载配置的Spring Boot运行状况指示器。可以通过设置health.config.enabled=false来禁用运行状况指示器。由于性能原因,响应也被缓存。默认缓存生存时间为5分钟。要更改该值,请设置health.config.time-to-live属性(以毫秒为单位)。
推送通知和Spring Cloud Bus
许多源代码存储库提供程序(例如Github,Gitlab或Bitbucket)将通过webhook通知您存储库中的更改。您可以通过提供商的用户界面将webhook配置为URL和一组感兴趣的事件。例如, Github 将使用包含提交列表的JSON主体和“X-Github-Event”等于“push”的头文件发送到webhook。如果您在spring-cloud-config-monitor库中添加依赖关系并激活配置服务器中的Spring Cloud Bus,则启用“/ monitor”端点。
当Webhook被激活时,配置服务器将发送一个RefreshRemoteApplicationEvent针对他认为可能已经改变的应用程序。变更检测可以进行策略化,但默认情况下,它只是查找与应用程序名称匹配的文件的更改(例如,“foo.properties”针对的是“foo”应用程序,“application.properties”针对所有应用程序) 。如果要覆盖该行为的策略是PropertyPathNotificationExtractor,它接受请求标头和正文作为参数,并返回更改的文件路径列表。
默认配置与Github,Gitlab或Bitbucket配合使用。除了Github,Gitlab或Bitbucket的JSON通知之外,您还可以通过使用表单编码的身体参数path={name}通过POST为“/ monitor”来触发更改通知。这将广播到匹配“{name}”模式的应用程序(可以包含通配符)。
注意
只有在配置服务器和客户端应用程序中激活spring-cloud-bus时才会传送RefreshRemoteApplicationEvent。
注意
默认配置还检测本地git存储库中的文件系统更改(在这种情况下不使用webhook,但是一旦编辑配置文件,将会播放刷新)。