官方文檔地址為 http://cloud.spring.io/spring-cloud-static/Dalston.SR3/#_spring_cloud_config 經過了幾個課題的翻譯,這次就不放原文了。 ...
官方文檔地址為:http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#spring-cloud-feign
文中例子我做了一些測試在:http://git.oschina.net/dreamingodd/spring-cloud-preparation
官方項目:https://github.com/spring-cloud-samples/config-repo
II.Spring Cloud Config
Dalston.SR2
Spring Cloud Config為分散式系統的外部配置提供客戶端的服務端的支持。使用了它,開發人員就可以在一個中心倉庫管理應用程式在所有環境中的外部配置。伺服器和客戶端映射的概念都和Spring環境以及PropertySource的抽象完全相同,因此和Spring應用程式結合的相當好,並且支持任何語言編寫的任何程式。當應用程式隨著部署流程在DEV,TEST和PROD環境間遷移時,開發人員可以統一管理這些環境的配置,並且能確認應用程式擁有所有的運行所需的東西。伺服器後端伺服器預設使用git,因此,它可以輕鬆支持標簽版本的配置環境,並且可以被大多數內容管理工具訪問到。可以輕鬆添加替代實現,並使用Spring配置實現插拔。
4.快速開始
啟動伺服器:(可下載參考官方項目)
$ cd spring-cloud-config-server
$ ../mvnw spring-boot:run
此伺服器是一個Spring Boot應用,所以如果願意開發人員也可以在IDE中跑(main類為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。迷你SpringApplication用於枚舉屬性源並通過JSON節點發佈。
HTTP服務支持以下屬性數據源。
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
“application”是以SpringApplication的spring.config.name註入的(即常規Spring Boot應用程式中通常為“application”),“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的應用(例如:借鑒config-client的測試,或同一個app)。最便捷的方式時用過Spring Boot starter的org.springframework.cloud:spring-cloud-starter-config依賴。使用Maven的父pom(spring-cloud-starter-parent)或Gradle的Spring CLI,Spring IO version management properties file也可以。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); } }
App啟動時,它會從預設的本地配置伺服器的8888埠拉取外部配置,當然前提是伺服器已在8888啟動。使用bootstrap.properties切換配置伺服器的地址開發人員能夠改變應用啟動的行為(就像一個應用程式上下文在程式引導階段使用的application.properties),例如:
spring.cloud.config.uri: http://myconfigserver.com
bootstrap屬性將作為高優先順序屬性源顯示在/env的鏈接返回結果中,例如:
$ curl localhost:8080/env
{
"profiles":[],"configService:https://github.com/spring-cloud-samples/config-repo/bar.properties":{"foo":"bar"},
"servletContextInitParams":{}, "systemProperties":{...},
...
}
(a property source called "configService:<URL of remote repository>/<file name>" contains the property "foo" with value "bar" and is highest priority).
(一個叫做"configService:<URL of remote repository>/<file name>"的最高優先順序屬性源包含一個值為“bar”的“foo“屬性)
NOTE the URL in the property source name is the git repository not the config server URL.
註意 屬性源名稱中的URL是git倉庫地址而不是配置伺服器的URL。
5.配置中心
Spring Cloud Config伺服器為外部配置提供了一個HTTP,基於資源的API(名稱-值對,或等價的YAML)。使用@EnableConfigServer註解,伺服器能輕易嵌入Spring Boot應用。故這個應用就是一個配置伺服器:
ConfigServer.java
@SpringBootApplication@EnableConfigServerpublic class ConfigServer { public static void main(String[] args) { SpringApplication.run(ConfigServer.class, args); } }
與通用的Spring Boot應用一樣,伺服器預設跑在8080埠上,開發人員可以使用多種方式換成8888埠。最簡單的方式是,發佈為spring.config.name=configserver(配置伺服器jar包中有一個configserver.yml),同時將其設定為一個配置倉庫。另一種方式是使用自身的application.properties(application.yml),如下:
application.properties
server.port: 8888
spring.cloud.config.server.git.uri: file://${user.home}/config-repo
其中${user.home}/config-repo為包含了YAML和屬性文件的git倉庫。
註意 在Windows系統中如果路徑是一個帶盤符的絕對路徑,那麼開發人員需要額外的“/”,如下: 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的淺層次拷貝(主要包含屬性源)。Environment數據源由三個變數參數化:
{application}由客戶端的"spring.application.name"屬性指定
{profile}由客戶端的"spring.profiles.active"屬性指定
{label}為伺服器的標註“版本”配置集(git為分支)
倉庫實現通常與Spring Boot應用一樣,從“spring.config.name”和“spring.profiles.active”(也就是{application}和{profiles})載入配置文件。Profiles的優先順序規則也和普通的應用一樣:active的profile優先於預設配置,還有,如果有多個profiles,那麼應用最後一個(就像在Map中添加數據一樣)。
示例:一個客戶端應用程式和他的bootstrap配置:
bootstrap.yml
spring: application: name: foo profiles: active: dev,mysql
(當然和Spring Boot應用一樣,這些屬性也可以在環境變數和命令行中定義)。
如果倉庫是基於文件的,那麼伺服器會從application.yml(被所有客戶端共用)和foo.yml(優先順序高)中創建環境。如果YAML文件中有文檔指向Spring profiles,則應用較高優先順序(根據profiles列出的順序),如果指明profile的YAML文件,那麼這些文件的優先順序也比預設的高。高優先順序的配置將在環境中率先轉換為PropertySource。
Git後端
EnvironmentRepository的預設實現使用了Git,這種方式可以便捷的管理升級和物理環境以及審核修改。修改倉庫地址只需要在配置中心修改"spring.cloud.config.server.git.uri"(application.yml)。如果用文件設置:首碼設置它,它應該從本地存儲庫中運行,以便在沒有伺服器的情況下快速輕鬆地啟動,但在這種情況下,伺服器直接在本地存儲庫上操作,而不克隆它(它是不是裸機不重要,因為配置中心從不對“遠程”存儲庫進行更改。要擴展中心並使其高度可用,開發人員需要將伺服器的所有實例指向同一個存儲庫,這樣共用文件系統才能正常工作。即使在這種情況下,最好使用ssh:協議用於共用文件系統存儲庫,以便伺服器可以將其克隆,並將本地工作副本用作緩存。
這個倉庫實現將HTTP資源的{label}參數映射到git標簽(commit,branch或tag)。如果git branch或tag中有斜線(/),那麼HTTP URL的標簽需要用特定字元串"()"代替指定(避免URL歧義)。例如,若標簽為foo/bar,則替換為foo()bar。註意若使用命令行工具的話,URL中的()需要特殊處理(例如,在shell中使用"轉義)。
Git URI中的占位符
Spring Cloud Config Server支持git倉庫URL中的{application}和{profile}占位符(若需要,也支持{label},但記住標簽應用為git標簽)。因此,開發人員可以輕鬆支持“一個應用一套配置”的策略。
spring: cloud: config: server: git: uri: https://github.com/myorg/{application}
或使用一樣的模式加上{profile}實現“一個profile一套配置”的策略。
多倉庫pattern匹配
還可以通過application和profile的pattern匹配來支持更複雜的需求。pattern的格式是帶有通配符的{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}與任何pattern不匹配,它將使用“spring.cloud.config.server.git.uri”下定義的預設uri。 在上面的例子中,對於“simple”倉庫,pattern為simple/*(即它只匹配一個在所有配置文件中名為“simple”的應用程式)。 “local”倉庫將所有配置文件中以“local”開頭的所有應用程式名稱匹配(/*尾碼自動添加到任何沒有不匹配profile的pattern)。
註意 上文simple的一行快捷設置只能在僅設定URI的場合使用。設置其他任何值都不能再用這種方式。repo中的pattern屬性其實是一個數組,因此開發人員也可以使用YAML數組(或[0],[1]等尾碼)綁定到多個patterns。這是為了運行不同profile的多個程式。示例:
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會認為不以結尾的配置文件的pattern意味著實際上要匹配一個以此pattern開頭的配置文件列表(/staging是["/staging", "/staging,*"]的快捷方式)。這很常見,例如開發人員需要在本地跑"development" profile,同時在遠程跑"cloud" profile。
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倉庫克隆了配置。其他兩個要在請求之後。
註意 啟動時克隆可以快速定位錯誤的配置源(如無效的倉庫URI)。若cloneOnStart為false,那麼服務可能會在配置源錯誤的情況下順利啟動,併在應用請求的時候才發現配置源錯誤了。
安全認證
使用基本的HTTP安全認證只需分別加入用戶名和密碼,例如:
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-configuration"。重要的是,Git伺服器的入口存在於/.ssh/known_hosts文件中,並且以ssh-rsa格式存在。 其他格式(像ecdsa-sha2-nistp256)均不支持。為了避免意外,應確保Git伺服器的known_hosts文件中只有一個入口,並且與您提供給配置伺服器的URL相匹配。如果開發人員在URL中使用了主機名,那麼需要在known_hosts文件中有這個名稱,而不是IP。當使用JGit訪問存儲庫,任何文檔都適用。HTTPS代理選項可以在~/.git/config中設置,或通過類似於JVM進程的系統變數(-Dhttps.proxyHost and -Dhttps.proxyPort)。
提示 如果找不到~/.git文件夾,使用git config --global設置(例如git config --global http.sslVerify false)。
AWS CodeCommit的安全認證(這段用不上)
AWS CodeCommit authentication can also be done. AWS CodeCommit uses an authentication helper when using Git from the command line. This helper is not used with the JGit library, so a JGit CredentialProvider for AWS CodeCommit will be created if the Git URI matches the AWS CodeCommit pattern. AWS CodeCommit URIs always look like https://git-codecommit.${AWS_REGION}.amazonaws.com/${repopath}.
If you provide a username and password with an AWS CodeCommit URI, then these must be the AWS accessKeyId and secretAccessKey to be used to access the repository. If you do not specify a username and password, then the accessKeyId and secretAccessKey will be retrieved using the AWS Default Credential Provider Chain.
If your Git URI matches the CodeCommit URI pattern (above) then you must provide valid AWS credentials in the username and password, or in one of the locations supported by the default credential provider chain. AWS EC2 instances may use IAM Roles for EC2 Instances.
Note: The aws-java-sdk-core jar is an optional dependency. If the aws-java-sdk-core jar is not on your classpath, then the AWS Code Commit credential provider will not be created regardless of the git server URI.
Git SSH屬性配置
預設情況下,當通過SSH URI連接Git倉庫的時候,Spring Cloud Config Server的JGit library使用SSH配置文件如~/.ssh/known_hosts和/etc/ssh/ssh_config。在類似Cloud Foundry的雲環境下,本地文件系統可能是短暫的或難以訪問的。這些情況下,可以使用Java屬性去設置SSH配置。為了激活基於屬性的SSH配置,須將屬性spring.cloud.config.server.git.ignoreLocalSshSettings設置為true。例:
spring: cloud: config: server: git: uri: [email protected]:team/repo1.git ignoreLocalSshSettings: true hostKey: someHostKey hostKeyAlgorithm: ssh-rsa privateKey: | -----BEGIN RSA PRIVATE KEY----- MIIEpgIBAAKCAQEAx4UbaDzY5xjW6hc9jwN0mX33XpTDVW9WqHp5AKaRbtAC3DqX IXFMPgw3K45jxRb93f8tv9vL3rD9CUG1Gv4FM+o7ds7FRES5RTjv2RT/JVNJCoqF ol8+ngLqRZCyBtQN7zYByWMRirPGoDUqdPYrj2yq+ObBBNhg5N+hOwKjjpzdj2Ud 1l7R+wxIqmJo1IYyy16xS8WsjyQuyC0lL456qkd5BDZ0Ag8j2X9H9D5220Ln7s9i oezTipXipS7p7Jekf3Ywx6abJwOmB0rX79dV4qiNcGgzATnG1PkXxqt76VhcGa0W DDVHEEYGbSQ6hIGSh0I7BQun0aLRZojfE3gqHQIDAQABAoIBAQCZmGrk8BK6tXCd fY6yTiKxFzwb38IQP0ojIUWNrq0+9Xt+NsypviLHkXfXXCKKU4zUHeIGVRq5MN9b BO56/RrcQHHOoJdUWuOV2qMqJvPUtC0CpGkD+valhfD75MxoXU7s3FK7yjxy3rsG EmfA6tHV8/4a5umo5TqSd2YTm5B19AhRqiuUVI1wTB41DjULUGiMYrnYrhzQlVvj 5MjnKTlYu3V8PoYDfv1GmxPPh6vlpafXEeEYN8VB97e5x3DGHjZ5UrurAmTLTdO8 +AahyoKsIY612TkkQthJlt7FJAwnCGMgY6podzzvzICLFmmTXYiZ/28I4BX/mOSe pZVnfRixAoGBAO6Uiwt40/PKs53mCEWngslSCsh9oGAaLTf/XdvMns5VmuyyAyKG ti8Ol5wqBMi4GIUzjbgUvSUt+IowIrG3f5tN85wpjQ1UGVcpTnl5Qo9xaS1PFScQ xrtWZ9eNj2TsIAMp/svJsyGG3OibxfnuAIpSXNQiJPwRlW3irzpGgVx/AoGBANYW dnhshUcEHMJi3aXwR12OTDnaLoanVGLwLnkqLSYUZA7ZegpKq90UAuBdcEfgdpyi PhKpeaeIiAaNnFo8m9aoTKr+7I6/uMTlwrVnfrsVTZv3orxjwQV20YIBCVRKD1uX VhE0ozPZxwwKSPAFocpyWpGHGreGF1AIYBE9UBtjAoGBAI8bfPgJpyFyMiGBjO6z FwlJc/xlFqDusrcHL7abW5qq0L4v3R+FrJw3ZYufzLTVcKfdj6GelwJJO+8wBm+R gTKYJItEhT48duLIfTDyIpHGVm9+I1MGhh5zKuCqIhxIYr9jHloBB7kRm0rPvYY4 VAykcNgyDvtAVODP+4m6JvhjAoGBALbtTqErKN47V0+JJpapLnF0KxGrqeGIjIRV cYA6V4WYGr7NeIfesecfOC356PyhgPfpcVyEztwlvwTKb3RzIT1TZN8fH4YBr6Ee KTbTjefRFhVUjQqnucAvfGi29f+9oE3Ei9f7wA+H35ocF6JvTYUsHNMIO/3gZ38N CPjyCMa9AoGBAMhsITNe3QcbsXAbdUR00dDsIFVROzyFJ2m40i4KCRM35bC/BIBs q0TY3we+ERB40U8Z2BvU61QuwaunJ2+uGadHo58VSVdggqAo0BSkH58innKKt96J 69pcVH/4rmLbXdcmNYGm6iu+MlPQk4BUZknHSmVHIFdJ0EPupVaQ8RHT -----END RSA PRIVATE KEY-----
表1-SSH 配置屬性
Property Name |
Remarks |
ignoreLocalSshSettings |
true:使用基於屬性的SSH代替基於文件的SSH。需通過spring.cloud.config.server.git.ignoreLo calSshSettings設置,而不能在一個倉庫中定義。 |
privateKey |
合法的SSH私有密鑰。若ignoreLocalSshSettings為true且Git URI是SSH格式的,則必須設置。 |
hostKey |
合法的SSH主機主機密鑰。若設置了hostKeyAlgorithm,則必須設置 |
hostKeyAlgorithm |
ssh-dss, ssh-rsa, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384 ,ecdsa-sha2-nistp521之中一個,必須設置若hostKey設置了。 |
strictHostKeyChecking |
true或false. 若為false,則忽略host key的錯誤。 |
Git搜索路徑的占位符
Spring Cloud Config Server也支持搜索路徑的占位符如{application}和{profile}(若需要{label}也支持)。例如:
Spring Cloud Config Server
spring: cloud: config: server: git: uri: https://github.com/spring-cloud-samples/config-repo searchPaths: '{application}'
在倉庫中搜索與目錄(以及頂級)相同名稱的文件。在占位符中使用通配符也是有效的(搜索中包含任何匹配的目錄)。
Git倉庫的強制拉取
如前所述,Spring Cloud Config Server克隆了遠程git倉庫,如果本地副本被污染了,則Spring Cloud Config Server無法從遠程倉庫更新本地副本。
為解決這個問題,當本地副本被污染,Spring Cloud Config Server提供了force-pull屬性來讓其強制從遠程伺服器拉取配置。
spring: cloud: config: server: git: uri: https://github.com/spring-cloud-samples/config-repo force-pull: true
若有多個倉庫配置,那麼可以為每個都配置上這個屬性。如下:
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。
使用版本控制後端伺服器
警告 當使用基於版本控制的後端(git,svn)時,文件被克隆到本地文件系統。它們會被預設放在系統的帶config-repo-首碼的臨時目錄下。例如在linux系統中,它是/tmp/config-repo-<randomid>。有些操作系統定期清理臨時文件。這會導致如丟失屬性這樣不可預知的錯誤。為避免這種情況出現,要通過設置spring.cloud.config.server.git.basedir或spring.cloud.config.server.svn.basedir到一個非臨時文件的文件結構中,讓配置中心使用這個值。
文件系統後端
配置中心還有個不使用Git的“原生”配置,它從本地classpath或文件系統載入配置文件(使用spring.cloud.config.server.native.searchLocations指向任何的靜態URL)。啟動配置中心時加上spring.profiles.active=native參數就可以使用這個原生配置。
註意 記住使用文件時:文件資源要加首碼(沒有首碼的通常是classpath里的)。跟Spring Boot配置一樣,可以使用${}風格的占位符,但記住windows的絕對路徑需要一個額外的"/",例如:file:///${user.home}/config-repo
警告 預設searchLocations的值適合本地Spring Boot應用完全相同的([classpath:/, classpath:/config, file:./, file:./config])。這不會把伺服器的application.properties暴露給所有的客戶端,因為伺服器所有存在的屬性源在發送到客戶端之前就已經被刪除了。
提示 本地文件系統適合初學者的測試。在生產環境使用的話,必須保證文件系統的可靠性,併在配置中心的所有實例間共用。
搜索欄位可以包括{application},{profile}和{label}。這樣開發人員可以在路徑中隔離文件夾,並選擇一個適合的策略(例如每個應用一個子文件夾,或每個profile一個子文件夾)。
如果不使用占位符,那麼倉庫將把HTTP資源的{label}參數加到搜索路徑上的尾碼,所以屬性文件將從從每個搜索位置和一個與標簽名稱相同的子目錄載入(標記屬性在Spring環境中優先)。因此,沒有占位符的話,預設與添加以/{label}/結尾的搜索位置一樣。比如 file:/tmp/config 和 file:/tmp/config,file:/tmp/config/{label}一樣。禁用這個功能可以通過設定spring.cloud.config.server.native.addLabelLocations=false。
Vault後端
Spring Cloud Config Server also sup