https://springcloud.cc/spring-cloud-config.htmlhtml
目錄java
1.3.0.RELEASEmysql
Spring Cloud Config爲分佈式系統中的外部配置提供服務器和客戶端支持。使用Config Server,您能夠在全部環境中管理應用程序的外部屬性。客戶端和服務器上的概念映射與Spring Environment
和PropertySource
抽象相同,所以它們與Spring應用程序很是契合,但能夠與任何以任何語言運行的應用程序一塊兒使用。隨着應用程序經過從開發人員到測試和生產的部署流程,您能夠管理這些環境之間的配置,並肯定應用程序具備遷移時須要運行的一切。服務器存儲後端的默認實現使用git,所以它輕鬆支持標籤版本的配置環境,以及能夠訪問用於管理內容的各類工具。能夠輕鬆添加替代實現,並使用Spring配置將其插入。linux
啓動服務器:nginx
$ cd spring-cloud-config-server $ ../mvnw spring-boot:run
該服務器是一個Spring Boot應用程序,因此你能夠從IDE運行它,而不是喜歡(主類是ConfigServerApplication
)。而後嘗試一個客戶端:git
$ 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端點發布。github
HTTP服務具備如下格式的資源:web
/{application}/{profile}[/{label}] /{application}-{profile}.yml /{label}/{application}-{profile}.yml /{application}-{profile}.properties /{label}/{application}-{profile}.properties
其中「應用程序」做爲SpringApplication
中的spring.config.name
注入(即常規Spring Boot應用程序中一般爲「應用程序」),「配置文件」是活動配置文件(或逗號分隔列表)的屬性),「label」是可選的git標籤(默認爲「master」)。spring
Spring Cloud Config服務器從git存儲庫中提取遠程客戶端的配置(必須提供):sql
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用戶的父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>1.3.5.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Brixton.RELEASE</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); } }
當它運行它將從端口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":{...}, ... }
(名爲「configService:<遠程存儲庫的URL> / <文件名>」的屬性源包含值爲「bar」的屬性「foo」,是最高優先級)。
注意 |
屬性源名稱中的URL是git存儲庫,而不是配置服務器URL。 |
服務器爲外部配置(名稱值對或等效的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
屬性。例:
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
注意 |
force-pull 屬性的默認值爲false 。 |
版本控制後端文件系統使用
警告 |
使用基於VCS的後端(git,svn)文件被檢出或克隆到本地文件系統。默認狀況下,它們放在系統臨時目錄中,前綴爲config-repo- 。在linux上,例如能夠是/tmp/config-repo-<randomid> 。一些操做系統會按期清除臨時目錄。這可能會致使意外的行爲,例如缺乏屬性。爲避免此問題,請經過將spring.cloud.config.server.git.basedir 或spring.cloud.config.server.svn.basedir 設置爲不在系統臨時結構中的目錄來更改Config Server所使用的目錄。 |
文件系統後端
配置服務器中還有一個不使用Git的「本機」配置文件,只是從本地類路徑或文件系統加載配置文件(您想要指向的任何靜態URL「spring.cloud.config.server .native.searchLocations「)。要使用本機配置文件,只需使用「spring.profiles.active = native」啓動Config Server。
注意 |
記住使用file: 前綴的文件資源(缺省沒有前綴一般是classpath)。與任何Spring Boot配置同樣,您能夠嵌入${} 樣式的環境佔位符,但請記住,Windows中的絕對路徑須要額外的「/」,例如file:///${user.home}/config-repo |
警告 |
searchLocations 的默認值與本地Spring Boot應用程序(因此[classpath:/, classpath:/config, file:./, file:./config] )相同。這不會將application.properties 從服務器暴露給全部客戶端,由於在發送到客戶端以前,服務器中存在的任何屬性源都將被刪除。 |
提示 |
文件系統後端對於快速入門和測試是很是好的。要在生產中使用它,您須要確保文件系統是可靠的,並在配置服務器的全部實例中共享。 |
搜索位置能夠包含{application}
,{profile}
和{label}
的佔位符。以這種方式,您能夠隔離路徑中的目錄,並選擇一個有用的策略(例如每一個應用程序的子目錄或每一個配置文件的子目錄)。
若是您不在搜索位置使用佔位符,則該存儲庫還將HTTP資源的{label}
參數附加到搜索路徑上的後綴,所以屬性文件將從每一個搜索位置加載並具備相同名稱的子目錄做爲標籤(標籤屬性在Spring環境中優先)。所以,沒有佔位符的默認行爲與添加以/{label}/. For example `file:/tmp/config
結尾的搜索位置的添加與file:/tmp/config,file:/tmp/config/{label}
相同
Vault後端
Spring Cloud Config服務器還支持Vault做爲後端。
Vault是安全訪問祕密的工具。一個祕密是你想要嚴格控制訪問的任何東西,如API密鑰,密碼,證書等等。Vault爲任何祕密提供統一的界面,同時提供嚴格的訪問控制和記錄詳細的審覈日誌。
有關Vault的更多信息,請參閱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
。
名稱 | 默認值 |
---|---|
主辦 |
127.0.0.1 |
港口 |
8200 |
方案 |
HTTP |
後端 |
祕密 |
defaultKey |
應用 |
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"
在提出上述要求後,您應該會看到相似的回覆。
{ "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
配置文件時,寫入全部上述路徑的屬性將可用,列表中第一個路徑中的屬性優先於其餘路徑。
與全部應用共享配置
基於文件的存儲庫
使用基於文件(即git,svn和native)的存儲庫,全部客戶端應用程序(application.properties
,application.yml
,application-*.properties
等))共享文件名爲application*
的資源。您可使用這些文件名的資源來配置全局默認值,並根據須要將其覆蓋應用程序特定的文件。
#_property_overrides [屬性覆蓋]功能也可用於設置全局默認值,而且容許佔位符應用程序在本地覆蓋它們。
提示 |
使用「本機」配置文件(本地文件系統後端),建議您使用不屬於服務器自身配置的顯式搜索位置。不然,默認搜索位置中的application* 資源將被刪除,由於它們是服務器的一部分。 |
Vault服務器
當使用Vault做爲後端時,您能夠經過將配置放在secret/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
屬性的數值越低,優先級越高。存儲庫的優先順序將有助於解決包含相同屬性的值的存儲庫之間的任何潛在衝突。
注意 |
從環境倉庫檢索值時的任何類型的故障將致使整個複合環境的故障。 |
注意 |
當使用複合環境時,重要的是全部repos都包含相同的標籤。若是您有相似於上述的環境,而且使用標籤master 請求配置數據,可是SVN repo不包含稱爲master 的分支,則整個請求將失敗。 |
自定義複合環境庫
除了使用Spring Cloud中的一個環境存儲庫以外,還能夠提供本身的EnvironmentRepository
bean做爲複合環境的一部分。要作到這一點,你的bean必須實現EnvironmentRepository
接口。若是您想在複合環境中控制自定義EnvironmentRepository
的優先級,您還應該實現Ordered
接口並覆蓋getOrdered
方法。若是您不實現Ordered
接口,則您的EnvironmentRepository
將被賦予最低優先級。
屬性覆蓋
Config Server具備「覆蓋」功能,容許操做員爲全部應用程序提供配置屬性,這些應用程序不會被應用程序使用正常的Spring Boot鉤子意外更改。要聲明覆蓋只是將名稱/值對的地圖添加到spring.cloud.config.server.overrides
。例如
spring: cloud: config: server: overrides: foo: bar
將致使配置客戶端的全部應用程序獨立於本身的配置讀取foo=bar
。(固然,應用程序能夠以任何方式使用Config Server中的數據,所以覆蓋不可強制執行,但若是它們是Spring Cloud Config客戶端,則它們會提供有用的默認行爲。)
提示 |
一般使用「$ {}」的Spring環境佔位符可使用反斜槓(「\」)來轉義(並在客戶端上解析)來轉義「$」或「{」,例如\${app.foo:bar} 解析爲「bar 「除非該應用程序提供本身的」app.foo「。請注意,在YAML中,您不須要轉義反斜槓自己,而是在您執行的屬性文件中配置服務器上的覆蓋。 |
您能夠將客戶端中全部覆蓋的優先級更改成更爲默認值,容許應用程序經過在遠程存儲庫中設置標誌spring.cloud.config.overrideNone=true
(默認值爲false),在環境變量或系統屬性中提供本身的值。
配置服務器附帶運行情況指示器,檢查配置的EnvironmentRepository
是否正常工做。默認狀況下,它要求EnvironmentRepository
應用程序名爲app
,default
配置文件和EnvironmentRepository
實現提供的默認標籤。
您能夠配置運行情況指示器以檢查更多應用程序以及自定義配置文件和自定義標籤,例如
spring: cloud: config: server: health: repositories: myservice: label: mylabel myservice-dev: name: myservice profiles: development
您能夠經過設置spring.cloud.config.server.health.enabled=false
來禁用運行情況指示器。
您能夠以任何對您有意義的方式(從物理網絡安全性到OAuth2承載令牌)來保護您的Config Server,而Spring Security和Spring Boot能夠輕鬆作任何事情。
要使用默認的Spring Boot配置的HTTP Basic安全性,只需在類路徑中包含Spring Security(例如,經過spring-boot-starter-security
)。默認是「user」的用戶名和隨機生成的密碼,這在實踐中不會很是有用,所以咱們建議您配置密碼(經過security.user.password
)進行加密(有關如下內容的說明,請參閱如下內容)怎麼作)。
重要 |
先決條件:要使用加密和解密功能,您須要在JVM中安裝全面的JCE(默認狀況下不存在)。您能夠從Oracle下載「Java加密擴展(JCE)無限強度管理策略文件」,並按照安裝說明(實際上將JRE lib / security目錄中的2個策略文件替換爲您下載的文件)。 |
若是遠程屬性源包含加密內容(以{cipher}
開頭的值)),則在經過HTTP發送給客戶端以前,它們將被解密。這種設置的主要優勢是,當它們「靜止」時,屬性值沒必要是純文本(例如在git倉庫中)。若是值沒法解密,則從屬性源中刪除該值,並添加具備相同鍵的附加屬性,但以「無效」做爲前綴。和「不適用」的值(一般爲「<n / a>」)。這主要是爲了防止密碼被用做密碼並意外泄漏。
若是要爲配置客戶端應用程序設置遠程配置存儲庫,可能會包含一個application.yml
,例如:
application.yml
spring: datasource: username: dbuser password: '{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ'
.properties文件中的加密值不能用引號括起來,不然不會解密該值:
application.properties
spring.datasource.username: dbuser spring.datasource.password: {cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ
您能夠安全地將此純文本推送到共享git存儲庫,而且保密密碼。
服務器還暴露了/encrypt
和/decrypt
端點(假設這些端點將被保護而且只能由受權代理訪問)。若是您正在編輯遠程配置文件,可使用Config Server經過POST到/encrypt
端點來加密值,例如
$ curl localhost:8888/encrypt -d mysecret 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
注意 |
若是要加密的值具備須要進行URL編碼的字符,則應使用--data-urlencode 選項curl 來確保它們已正確編碼。 |
逆向操做也可經過/decrypt
得到(若是服務器配置了對稱密鑰或完整密鑰對):
$ curl localhost:8888/decrypt -d 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda mysecret
提示 |
若是您使用curl進行測試,則使用--data-urlencode (而不是-d )或設置顯式Content-Type: text/plain ,以確保在有特殊字符時正確地對數據進行編碼('+'特別是棘手)。 |
在加入值以前,先添加{cipher}
前綴,而後再將其放在YAML或屬性文件中,而後再提交併將其推送到遠程,可能不安全的存儲區。
/encrypt
和/decrypt
端點也都接受/*/{name}/{profiles}
形式的路徑,當客戶端調用到主環境資源時,可使用每一個應用程序(名稱)和配置文件控制密碼。
注意 |
爲了以這種細微的方式控制密碼,您還必須提供TextEncryptorLocator 類型的@Bean ,每一個名稱和配置文件都會建立一個不一樣的加密器。默認提供的不會這樣作(全部加密使用相同的密鑰)。 |
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+...
關鍵參數是強制性的(儘管有一個--
前綴)。
Config Server可使用對稱(共享)密鑰或非對稱密鑰(RSA密鑰對)。非對稱選擇在安全性方面是優越的,可是使用對稱密鑰每每更方便,由於它只是配置的一個屬性值。
要配置對稱密鑰,您只須要將encrypt.key
設置爲一個祕密字符串(或使用環境變量ENCRYPT_KEY
將其保留爲純文本配置文件)。
要配置非對稱密鑰,您能夠將密鑰設置爲PEM編碼的文本值(encrypt.key
)或經過密鑰庫(例如由JDK附帶的keytool
實用程序建立)。密鑰庫屬性爲encrypt.keyStore.*
,*
等於
location
(Resource
位置),
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}
前綴以外,配置服務器在(Base64編碼)密文開始以前查找{name:value}
前綴(零或多個)。密鑰被傳遞給TextEncryptorLocator
,它能夠執行找到密碼的TextEncryptor
所需的任何邏輯。若是配置了密鑰庫(encrypt.keystore.location
),默認定位器將使用「key」前綴提供的別名,即便用以下密碼來查找存儲中的密鑰:
foo: bar: `{cipher}{key:testkey}...`
定位器將尋找一個名爲「testkey」的鍵。也能夠經過前綴中的{secret:…}
值提供一個祕密,可是若是不是默認值,則使用密鑰庫密碼(這是您構建密鑰存儲而且不指定密碼時得到的密碼)。若是你這樣作 提供一個祕密建議你也加密使用自定義SecretLocator
的祕密。
若是密鑰只用於加密幾個字節的配置數據(即它們沒有在其餘地方使用),則密碼轉換幾乎不是必需的,可是若是存在安全漏洞,有時您可能須要更改密鑰實例。在這種狀況下,全部客戶端都須要更改其源配置文件(例如git),並在全部密碼中使用新的{key:…}
前綴,固然,先檢查配置服務器密鑰庫中的密鑰別名可用。
提示 |
若是要讓Config Server處理全部加密以及解密,也能夠將{name:value} 前綴添加到發佈到/encrypt 端點的明文。 |
有時您但願客戶端在本地解密配置,而不是在服務器中進行配置。在這種狀況下,您仍然能夠擁有/加密和/解密端點(若是提供encrypt.*
配置來定位密鑰),可是您須要使用spring.cloud.config.server.encrypt.enabled=false
明確地關閉傳出屬性的解密。若是您不關心端點,那麼若是您既不配置密鑰也不配置使能的標誌,則應該起做用。
來自環境端點的默認JSON格式對於Spring應用程序的消耗是完美的,由於它直接映射到Environment
抽象。若是您喜歡,能夠經過向資源路徑(「.yml」,「.yaml」或「.properties」)添加後綴來使用與YAML或Java屬性相同的數據。這對於不關心JSON端點的結構的應用程序的消費或其提供的額外的元數據多是有用的,例如,不使用Spring的應用程序可能會受益於此方法的簡單性。
YAML和屬性表示有一個額外的標誌(做爲布爾查詢參數resolvePlaceholders
提供)),以標示Spring ${…}
形式的原始文檔中的佔位符信號,在渲染以前應儘量在輸出中解析。這對於不瞭解Spring佔位符約定的消費者來講是一個有用的功能。
注意 |
使用YAML或屬性格式存在侷限性,主要是與元數據的丟失有關。JSON被構造爲屬性源的有序列表,例如,名稱與源相關聯。即便源的起源具備多個源,而且原始源文件的名稱丟失,YAML和屬性表也合併成一個映射。YAML表示不必定是後臺存儲庫中YAML源的忠實表示:它是由平面屬性源的列表構建的,而且必須對鍵的形式進行假設。 |
您的應用程序可能不須要使用Environment
抽象(或YAML中的其餘替表明示形式或屬性格式),而是根據本身的環境須要通用的純文本配置文件。配置服務器經過/{name}/{profile}/{label}/{path}
中的附加端點提供這些服務,其中「name」,「profile」和「label」的含義與常規環境端點相同,但「path」是文件名(例如log.xml
)。此端點的源文件位於與環境端點相同的方式:與屬性或YAML文件相同的搜索路徑,而不是聚合全部匹配的資源,只返回匹配的第一個。
資源位置後,使用正常格式(${…}
)的佔位符使用提供的應用程序名稱,配置文件和標籤的有效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; }
注意 |
就像環境配置的源文件同樣,「配置文件」用於解析文件名,因此若是你想要一個特定於文件的文件,那麼/*/development/*/logback.xml 將被一個名爲logback-development.xml 的文件解析(優先於logback.xml )。 |
配置服務器最好做爲獨立應用程序運行,但若是須要,能夠將其嵌入到另外一個應用程序中。只需使用@EnableConfigServer
註釋。在這種狀況下可使用的可選屬性是spring.cloud.config.server.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
庫中添加依賴關係並激活配置服務器中的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,可是一旦編輯配置文件,將會播放刷新)。 |
一個Spring Boot應用程序能夠當即利用Spring Config Server(或應用程序開發人員提供的其餘外部屬性源),而且還將獲取與Environment
更改事件相關的一些其餘有用功能。
這是在類路徑中具備Spring Cloud Config Client的任何應用程序的默認行爲。當配置客戶端啓動時,它將經過配置服務器(經過引導配置屬性spring.cloud.config.uri
)綁定並使用遠程屬性源初始化Spring Environment
。
這樣作的最終結果是全部想要使用配置服務器的客戶端應用程序都須要spring.cloud.config.uri
(默認爲「http:// localhost:8888」)的bootstrap.yml
(或環境變量) )。
若是您正在使用「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
屬性(以毫秒爲單位)。
提供自定義RestTemplate
在某些狀況下,您可能須要從客戶端自定義對配置服務器的請求。一般這涉及傳遞特殊的Authorization
標頭來對服務器的請求進行身份驗證。要提供自定義RestTemplate
,請按照如下步驟操做。
設置spring.cloud.config.enabled=false
以禁用現有的配置服務器屬性源。
使用PropertySourceLocator
的實現建立一個新的配置bean。
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做爲配置服務器的後端時,客戶端將須要爲服務器提供令牌以從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
。