4.0.5
Spring Cloud Config 為分散式系統中的外部化配置提供了伺服器端和客戶端支援。透過 Config Server,您可以集中管理跨所有環境的應用程式的外部屬性。客戶端和伺服器端的概念與 Spring 的 Environment
和 PropertySource
抽象完全對應,因此它們非常適合 Spring 應用程式,但也可用於任何語言編寫的任何應用程式。隨著應用程式從開發環境、測試環境遷移到生產環境,您可以管理這些環境之間的配置,並確保應用程式在遷移時擁有執行所需的一切。伺服器儲存後端的預設實現使用 git,因此它很容易支援帶標籤的配置環境版本,並且可以透過各種工具訪問來管理內容。新增替代實現並將其與 Spring 配置整合也非常容易。
快速入門
本快速入門將指導您使用 Spring Cloud Config Server 的伺服器端和客戶端。
首先,啟動伺服器,如下所示
$ cd spring-cloud-config-server $ ../mvnw spring-boot:run
伺服器是一個 Spring Boot 應用程式,因此如果您願意,可以從您的 IDE 執行它(主類是 ConfigServerApplication
)。
接下來嘗試客戶端,如下所示
$ curl localhost:8888/foo/development { "name": "foo", "profiles": [ "development" ] .... "propertySources": [ { "name": "https://github.com/spring-cloud-samples/config-repo/foo-development.properties", "source": { "bar": "spam", "foo": "from foo development" } }, { "name": "https://github.com/spring-cloud-samples/config-repo/foo.properties", "source": { "foo": "from foo props", "democonfigclient.message": "hello spring io" } }, ....
定位屬性源的預設策略是克隆一個 git 倉庫(位於 spring.cloud.config.server.git.uri
)並用它來初始化一個迷你 SpringApplication
。這個迷你應用程式的 Environment
用於列舉屬性源並在 JSON 端點發布它們。
HTTP 服務具有以下形式的資源
/{application}/{profile}[/{label}] /{application}-{profile}.yml /{label}/{application}-{profile}.yml /{application}-{profile}.properties /{label}/{application}-{profile}.properties
例如
curl localhost:8888/foo/development curl localhost:8888/foo/development/master curl localhost:8888/foo/development,db/master curl localhost:8888/foo-development.yml curl localhost:8888/foo-db.properties curl localhost:8888/master/foo-db.properties
其中 application
在 SpringApplication
中作為 spring.config.name
注入(在常規 Spring Boot 應用中通常是 application
),profile
是活動配置檔案(或逗號分隔的屬性列表),label
是可選的 git 標籤(預設為 master
)。
Spring Cloud Config Server 從各種來源為遠端客戶端拉取配置。以下示例從一個 git 倉庫(必須提供)獲取配置,如下所示
spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
其他來源包括任何相容 JDBC 的資料庫、Subversion、Hashicorp Vault、Credhub 和本地檔案系統。
客戶端使用
要在應用程式中使用這些功能,您可以將其構建為一個依賴於 spring-cloud-config-client 的 Spring Boot 應用程式(例如,參見 config-client 的測試用例或示例應用程式)。新增依賴項最方便的方法是使用 Spring Boot 啟動器 org.springframework.cloud:spring-cloud-starter-config
。Maven 使用者還有一個父 pom 和 BOM(spring-cloud-starter-parent
),Gradle 和 Spring CLI 使用者還有一個 Spring IO 版本管理屬性檔案。以下示例顯示了一個典型的 Maven 配置
<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 埠獲取外部配置。要修改啟動行為,您可以透過使用 application.properties
來更改配置伺服器的位置,如下所示
spring.config.import=optional:configserver:http://myconfigserver.com
預設情況下,如果沒有設定應用程式名稱,將使用 application
。要修改名稱,可以將以下屬性新增到 application.properties
檔案中
spring.application.name: myapp
設定屬性 `${spring.application.name}` 時,不要在您的應用程式名稱前面加上保留字 `application-`,以免出現無法解析正確屬性源的問題。 |
Config Server 屬性會作為高優先順序屬性源出現在 `/env` 端點中,如下所示。
$ curl localhost:8080/env { "activeProfiles": [], { "name": "servletContextInitParams", "properties": {} }, { "name": "configserver:https://github.com/spring-cloud-samples/config-repo/foo.properties", "properties": { "foo": { "value": "bar", "origin": "Config Server https://github.com/spring-cloud-samples/config-repo/foo.properties:2:12" } } }, ... }
名為 `configserver:<遠端倉庫 URL>/<檔名>` 的屬性源包含值為 `bar` 的 `foo` 屬性。
屬性源名稱中的 URL 是 git 倉庫,而不是配置伺服器 URL。 |
如果您使用 Spring Cloud Config Client,需要設定 `spring.config.import` 屬性才能繫結到 Config Server。您可以在Spring Cloud Config 參考指南中閱讀更多相關內容。 |
Spring Cloud Config Server
Spring Cloud Config Server 提供了一個基於 HTTP 資源的 API,用於外部配置(名稱-值對或等效的 YAML 內容)。透過使用 `@EnableConfigServer` 註解,該伺服器可以嵌入到 Spring Boot 應用程式中。因此,以下應用程式是一個配置伺服器
@SpringBootApplication
@EnableConfigServer
public class ConfigServer {
public static void main(String[] args) {
SpringApplication.run(ConfigServer.class, args);
}
}
與所有 Spring Boot 應用程式一樣,它預設在 8080 埠執行,但您可以透過各種方式將其切換到更常用的 8888 埠。最簡單的方法(也設定了預設配置倉庫)是使用 `spring.config.name=configserver` 啟動它(Config Server jar 中有一個 `configserver.yml`)。另一種方法是使用您自己的 `application.properties`,如下所示
server.port: 8888
spring.cloud.config.server.git.uri: file://${user.home}/config-repo
其中 `${user.home}/config-repo` 是一個包含 YAML 和 properties 檔案的 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 倉庫僅用於測試目的。在生產環境中,您應該使用伺服器來託管您的配置倉庫。 |
如果您的配置倉庫中只保留文字檔案,則首次克隆會快速高效。如果儲存二進位制檔案,特別是大型檔案,在首次請求配置時可能會遇到延遲,或在伺服器中遇到記憶體不足錯誤。 |
環境倉庫
您應該在哪裡儲存 Config Server 的配置資料?管理此行為的策略是 `EnvironmentRepository`,它提供 `Environment` 物件。此 `Environment` 是 Spring `Environment` 領域的淺複製(主要特徵是包含 `propertySources`)。`Environment` 資源由三個變數引數化
-
{application}
,在客戶端對映到spring.application.name
。 -
{profile}
,在客戶端對映到spring.profiles.active
(逗號分隔列表)。 -
{label}
,這是一個伺服器端功能,用於標記一組“版本化”的配置檔案。
倉庫實現通常表現得像一個 Spring Boot 應用程式,從與 {application}
引數相等的 `spring.config.name` 和與 {profiles}
引數相等的 `spring.profiles.active` 中載入配置檔案。配置檔案的優先順序規則與常規 Spring Boot 應用程式中相同:活動配置檔案優先於預設配置,如果存在多個配置檔案,則最後一個配置檔案獲勝(類似於向 `Map` 中新增條目)。
以下示例客戶端應用程式具有此引導配置
spring:
application:
name: foo
profiles:
active: dev,mysql
(與常規 Spring Boot 應用程式一樣,這些屬性也可以透過環境變數或命令列引數設定)。
如果倉庫是基於檔案的,伺服器會從 `application.yml`(所有客戶端共享)和 `foo.yml`(`foo.yml` 優先)建立一個 `Environment`。如果 YAML 檔案內部有指向 Spring 配置檔案的文件,則這些配置檔案的優先順序更高(按列出的配置檔案順序)。如果存在特定於配置檔案的 YAML(或 properties)檔案,這些檔案的優先順序也高於預設檔案。更高的優先順序意味著在 `Environment` 中更早列出的 `PropertySource`。(這些相同的規則也適用於獨立的 Spring Boot 應用程式)。
您可以將 `spring.cloud.config.server.accept-empty` 設定為 `false`,以便在找不到應用程式時伺服器返回 HTTP 404 狀態。預設情況下,此標誌設定為 `true`。
您不能將 `spring.main.*` 屬性放在遠端 `EnvironmentRepository` 中。這些屬性用作應用程式初始化的一部分。 |
Git 後端
EnvironmentRepository
的預設實現使用 Git 後端,這對於管理升級、物理環境和審計更改非常方便。要更改倉庫位置,可以在 Config Server 中設定 `spring.cloud.config.server.git.uri` 配置屬性(例如在 `application.yml` 中)。如果使用 `file:` 字首設定它,則應從本地倉庫工作,以便您可以快速輕鬆地開始,而無需伺服器。但是,在這種情況下,伺服器直接在本地倉庫上操作,而無需克隆它(即使它不是裸倉庫也沒關係,因為 Config Server 從不更改“遠端”倉庫)。要擴充套件 Config Server 並使其高可用,您需要將伺服器的所有例項指向同一個倉庫,因此只有共享檔案系統才能工作。即使在這種情況下,對於共享檔案系統倉庫,最好使用 `ssh:` 協議,以便伺服器可以克隆它並使用本地工作副本作為快取。
此倉庫實現將 HTTP 資源的 {label}
引數對映到 git 標籤(提交 ID、分支名稱或標籤)。如果 git 分支或標籤名稱包含斜槓(/
),則 HTTP URL 中的標籤應改用特殊字串 (_)
指定(以避免與其他 URL 路徑產生歧義)。例如,如果標籤是 foo/bar
,替換斜槓後將得到以下標籤:foo(_)bar
。特殊字串 (_)
的包含也可以應用於 {application}
引數。如果您使用諸如 curl 之類的命令列客戶端,請注意 URL 中的括號 - 您應該用單引號 ('') 從 shell 中轉義它們。
跳過 SSL 證書驗證
透過將 `git.skipSslValidation` 屬性設定為 `true`(預設為 `false`),可以停用配置伺服器對 Git 伺服器 SSL 證書的驗證。
spring:
cloud:
config:
server:
git:
uri: https://example.com/my/repo
skipSslValidation: true
設定 HTTP 連線超時
您可以配置配置伺服器等待獲取 HTTP 連線的時間(以秒為單位)。使用 `git.timeout` 屬性(預設為 `5`)。
spring:
cloud:
config:
server:
git:
uri: https://example.com/my/repo
timeout: 4
Git URI 中的佔位符
Spring Cloud Config Server 支援在 git 倉庫 URL 中使用 {application}
和 {profile}
的佔位符(如果需要也可以使用 {label}
,但請記住標籤無論如何都會作為 git 標籤應用)。因此,您可以使用類似於以下的結構來支援“每個應用程式一個倉庫”的策略
spring:
cloud:
config:
server:
git:
uri: https://github.com/myorg/{application}
您也可以使用類似的模式,但使用 {profile}
來支援“每個配置檔案一個倉庫”的策略。
此外,在您的 {application}
引數中使用特殊字串 "(_)" 可以支援多個組織,如下例所示
spring:
cloud:
config:
server:
git:
uri: https://github.com/{application}
其中 {application}
在請求時以以下格式提供:organization(_)application
。
模式匹配和多個倉庫
Spring Cloud Config 還支援更復雜的要求,可以在應用程式和配置檔名稱上進行模式匹配。模式格式是逗號分隔的 {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”倉庫,模式是 simple/*
(它只匹配所有配置檔案中名為 simple
的一個應用程式)。“local”倉庫匹配所有配置檔案中以 local
開頭的所有應用程式名稱(/*
字尾會自動新增到任何沒有配置檔案匹配器的模式中)。
“simple”示例中使用的“單行”快捷方式僅在需要設定的唯一屬性是 URI 時使用。如果您需要設定其他任何內容(憑據、模式等),則需要使用完整形式。 |
倉庫中的 `pattern` 屬性實際上是一個數組,因此您可以使用 YAML 陣列(或 properties 檔案中的 [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,*"] 等的快捷方式)。這在需要例如在本地執行“開發”配置檔案中的應用程式,同時在遠端執行“雲”配置檔案中的應用程式時很常見。 |
每個倉庫還可以選擇將配置檔案儲存在子目錄中,並且可以指定搜尋這些目錄的模式作為 search-paths
。以下示例顯示了頂級目錄中的配置檔案
spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
search-paths:
- 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: https://git/team-a/config-repo.git
team-b:
pattern: team-b-*
cloneOnStart: false
uri: https://git/team-b/config-repo.git
team-c:
pattern: team-c-*
uri: https://git/team-a/config-repo.git
在前面的示例中,伺服器在啟動時克隆 team-a 的 config-repo,然後才接受任何請求。所有其他倉庫直到從該倉庫請求配置時才會被克隆。
在 Config Server 啟動時設定要克隆的倉庫有助於在 Config Server 啟動過程中快速識別配置錯誤的配置源(例如無效的倉庫 URI)。如果沒有為配置源啟用 cloneOnStart ,則 Config Server 可能會成功啟動,即使配置源配置錯誤或無效,直到應用程式從該配置源請求配置時才檢測到錯誤。 |
認證
要在遠端倉庫上使用 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 位置(例如 `[email protected]:configuration/cloud-configuration`)時,SSH 也應該可以直接工作。重要的是 ~/.ssh/known_hosts
檔案中必須包含 Git 伺服器的條目,並且格式為 ssh-rsa
。不支援其他格式(例如 ecdsa-sha2-nistp256
)。為避免意外,您應確保 known_hosts
檔案中僅包含 Git 伺服器的一個條目,並且該條目與您提供給配置伺服器的 URL 匹配。如果您在 URL 中使用主機名,則希望 known_hosts
檔案中也使用完全相同的主機名(而不是 IP)。倉庫透過 JGit 訪問,因此您能找到的任何關於 JGit 的文件都應該適用。HTTPS 代理設定可以在 ~/.git/config
中設定,或者(與任何其他 JVM 程序相同的方式)透過系統屬性(-Dhttps.proxyHost
和 -Dhttps.proxyPort
)設定。
如果您不知道您的 ~/.git 目錄在哪裡,請使用 git config --global 來操作設定(例如,git config --global http.sslVerify false )。 |
JGit 需要 PEM 格式的 RSA 金鑰。下面是一個 ssh-keygen(來自 openssh)命令的示例,它將生成正確格式的金鑰
ssh-keygen -m PEM -t rsa -b 4096 -f ~/config_server_deploy_key.rsa
警告:使用 SSH 金鑰時,預期的 SSH 私鑰必須以
開頭。如果金鑰以 -----BEGIN RSA PRIVATE KEY-----
開頭,則在 Spring Cloud Config Server 啟動時將無法載入 RSA 金鑰。錯誤看起來像-----BEGIN OPENSSH PRIVATE KEY-----
- Error in object 'spring.cloud.config.server.git': codes [PrivateKeyIsValid.spring.cloud.config.server.git,PrivateKeyIsValid]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [spring.cloud.config.server.git.,]; arguments []; default message []]; default message [Property 'spring.cloud.config.server.git.privateKey' is not a valid private key]
要糾正上述錯誤,RSA 金鑰必須轉換為 PEM 格式。上面提供了一個使用 openssh 生成相應格式的新金鑰的示例。
使用 AWS CodeCommit 認證
Spring Cloud Config Server 也支援 AWS CodeCommit 認證。AWS CodeCommit 在命令列使用 Git 時使用一個認證助手。JGit 庫不使用此助手,因此如果 Git URI 匹配 AWS CodeCommit 模式,則會建立一個 AWS CodeCommit 的 JGit CredentialProvider。AWS CodeCommit URI 遵循以下模式
https://git-codecommit.${AWS_REGION}.amazonaws.com/v1/repos/${repo}
如果您隨 AWS CodeCommit URI 提供使用者名稱和密碼,它們必須是提供倉庫訪問許可權的 AWS accessKeyId 和 secretAccessKey。如果您未指定使用者名稱和密碼,則會使用 Default Credential Provider Chain 獲取 accessKeyId 和 secretAccessKey。
如果您的 Git URI 匹配 CodeCommit URI 模式(如前所示),則必須在使用者名稱和密碼中提供有效的 AWS 憑據,或在預設憑據提供者鏈支援的任一位置提供憑據。AWS EC2 例項可以使用 EC2 例項的 IAM 角色。
software.amazon.awssdk:auth jar 是一個可選依賴項。如果類路徑中沒有 software.amazon.awssdk:auth jar,則無論 git 伺服器 URI 如何,都不會建立 AWS Code Commit 憑據提供者。 |
使用 Google Cloud Source 認證
Spring Cloud Config Server 也支援針對 Google Cloud Source 倉庫進行認證。
如果您的 Git URI 使用 http
或 https
協議,並且域名是 source.developers.google.com
,則將使用 Google Cloud Source 憑據提供者。Google Cloud Source 倉庫 URI 的格式為 https://source.developers.google.com/p/${GCP_PROJECT}/r/${REPO}
。要獲取倉庫的 URI,請在 Google Cloud Source UI 中點選“克隆”,然後選擇“手動生成憑據”。不要生成任何憑據,只需複製顯示的 URI。
Google Cloud Source 憑據提供者將使用 Google Cloud Platform 應用程式預設憑據。有關如何為系統建立應用程式預設憑據的資訊,請參閱Google Cloud SDK 文件。此方法適用於開發環境中的使用者賬戶和生產環境中的服務賬戶。
com.google.auth:google-auth-library-oauth2-http 是一個可選依賴項。如果類路徑中沒有 google-auth-library-oauth2-http jar,則無論 git 伺服器 URI 如何,都不會建立 Google Cloud Source 憑據提供者。 |
Git SSH 配置使用屬性
預設情況下,Spring Cloud Config Server 使用的 JGit 庫在使用 SSH URI 連線到 Git 倉庫時,會使用 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-----
下表描述了 SSH 配置屬性。
屬性名稱 | 備註 |
---|---|
ignoreLocalSshSettings |
如果為 |
privateKey |
有效的 SSH 私鑰。如果 |
hostKey |
有效的 SSH 主機金鑰。如果 |
hostKeyAlgorithm |
以下之一: |
strictHostKeyChecking |
|
knownHostsFile |
自定義 |
preferredAuthentications |
覆蓋伺服器認證方法順序。如果伺服器在 |
Git 搜尋路徑中的佔位符
Spring Cloud Config Server 也支援帶有 {application}
和 {profile}
佔位符(以及 {label}
,如果需要)的搜尋路徑,如下例所示
spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
search-paths: '{application}'
前面的列表導致在倉庫中搜索與目錄同名的檔案(以及頂級目錄中的檔案)。帶有佔位符的搜尋路徑中也支援萬用字元(任何匹配的目錄都包含在搜尋中)。
在 Git 倉庫中強制拉取
如前所述,如果本地副本變得“髒”(例如,資料夾內容因作業系統程序而改變),導致 Spring Cloud Config Server 無法從遠端倉庫更新本地副本,它會克隆遠端 git 倉庫。
為了解決這個問題,有一個 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: https://git/team-a/config-repo.git
force-pull: true
team-b:
pattern: team-b-*
uri: https://git/team-b/config-repo.git
force-pull: true
team-c:
pattern: team-c-*
uri: https://git/team-a/config-repo.git
force-pull 屬性的預設值是 false 。 |
刪除 Git 倉庫中未跟蹤的分支
由於 Spring Cloud Config Server 在將分支檢出到本地倉庫(例如按標籤獲取屬性)後會保留遠端 git 倉庫的克隆,它會一直保留該分支,直到下次伺服器重啟(這將建立新的本地倉庫)。因此,可能會出現遠端分支已被刪除,但其本地副本仍然可用於獲取的情況。如果 Spring Cloud Config Server 客戶端服務以 --spring.cloud.config.label=deletedRemoteBranch,master
啟動,它將從 deletedRemoteBranch
本地分支獲取屬性,而不是從 master
獲取。
為了保持本地倉庫分支幹淨並與遠端同步,可以設定 deleteUntrackedBranches
屬性。它將使 Spring Cloud Config Server 強制刪除本地倉庫中未跟蹤的分支。示例
spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
deleteUntrackedBranches: true
deleteUntrackedBranches 屬性的預設值是 false 。 |
Git 重新整理率
您可以使用 spring.cloud.config.server.git.refreshRate
控制配置伺服器從 Git 後端獲取更新配置資料的頻率。此屬性的值以秒為單位指定。預設值為 0,表示配置伺服器在每次請求時都會從 Git 倉庫獲取更新的配置。
預設標籤
Git 使用的預設標籤是 main
。如果您未設定 spring.cloud.config.server.git.defaultLabel
且不存在名為 main
的分支,配置伺服器預設也會嘗試檢出名為 master
的分支。如果您想停用回退分支行為,可以將 spring.cloud.config.server.git.tryMasterBranch
設定為 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 使用的目錄更改為不在系統臨時目錄結構中的目錄。 |
檔案系統後端
Config Server 中還有一個“native”配置檔案,它不使用 Git,而是從本地類路徑或檔案系統載入配置檔案(可以使用 spring.cloud.config.server.native.searchLocations
指向任何靜態 URL)。要使用 native 配置檔案,請使用 spring.profiles.active=native
啟動 Config Server。
請記住為檔案資源使用 file: 字首(沒有字首時預設通常是類路徑)。與任何 Spring Boot 配置一樣,您可以嵌入 ${} 風格的環境佔位符,但請記住 Windows 中的絕對路徑需要額外加一個 / (例如,file:///${user.home}/config-repo )。 |
searchLocations 的預設值與本地 Spring Boot 應用程式相同(即 [classpath:/, classpath:/config, file:./, file:./config] )。這不會將伺服器中的 application.properties 公開給所有客戶端,因為伺服器中存在的任何屬性源在傳送給客戶端之前都會被移除。 |
檔案系統後端對於快速上手和測試非常有用。要在生產環境中使用它,需要確保檔案系統可靠並且在 Config Server 的所有例項之間共享。 |
搜尋位置可以包含 {application}
、{profile}
和 {label}
的佔位符。透過這種方式,您可以在路徑中隔離目錄,並選擇對您有意義的策略(例如,每個應用程式一個子目錄或每個配置檔案一個子目錄)。
如果您在搜尋位置中不使用佔位符,此倉庫還會將 HTTP 資源的 {label}
引數附加到搜尋路徑的字尾上,因此屬性檔案會從每個搜尋位置以及與標籤同名的子目錄中載入(帶標籤的屬性在 Spring Environment 中具有更高優先順序)。因此,沒有佔位符時的預設行為與新增以 /{label}/
結尾的搜尋位置相同。例如,file:/tmp/config
與 file:/tmp/config,file:/tmp/config/{label}
相同。可以透過設定 spring.cloud.config.server.native.addLabelLocations=false
來停用此行為。
Vault 後端
Spring Cloud Config Server 也支援將 Vault 作為後端。
有關 Vault 的更多資訊,請參閱Vault 快速入門指南。
要使配置伺服器使用 Vault 後端,您可以使用 vault
配置檔案執行您的配置伺服器。例如,在配置伺服器的 application.properties
中,可以新增 spring.profiles.active=vault
。
預設情況下,配置伺服器假定您的 Vault 伺服器執行在 http://127.0.0.1:8200
。它還假定後端名稱是 secret
,金鑰是 application
。所有這些預設值都可以在您的配置伺服器的 application.properties
中配置。下表描述了可配置的 Vault 屬性
名稱 | 預設值 |
---|---|
host |
127.0.0.1 |
port |
8200 |
scheme |
http |
backend |
secret |
defaultKey |
application |
profileSeparator |
, |
kvVersion |
1 |
skipSslValidation |
false |
timeout |
5 |
namespace |
null |
前面表格中的所有屬性都必須以 spring.cloud.config.server.vault 作為字首,或者放置在複合配置的正確 Vault 部分中。 |
所有可配置屬性都可以在 org.springframework.cloud.config.server.environment.VaultEnvironmentProperties
中找到。
Vault 0.10.0 引入了版本化的鍵值後端(k/v 後端版本 2),它與早期版本公開了不同的 API,現在需要在掛載路徑和實際上下文路徑之間加上 data/ ,並將秘密資訊包裝在一個 data 物件中。設定 spring.cloud.config.server.vault.kv-version=2 將考慮這一點。 |
可選地,支援 Vault Enterprise 的 X-Vault-Namespace
頭部。要將其傳送到 Vault,請設定 namespace
屬性。
Config Server 執行後,您可以向伺服器發起 HTTP 請求以從 Vault 後端檢索值。為此,您需要 Vault 伺服器的令牌。
首先,在 Vault 中放置一些資料,如下例所示:
$ vault kv put secret/application foo=bar baz=bam
$ vault kv put secret/myapp foo=myappsbar
其次,向 Config Server 發起 HTTP 請求以檢索值,如下例所示:
$ curl -X "GET" "https://: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"
}
}
]
}
客戶端向 Config Server 提供與 Vault 通訊所需身份驗證的預設方式是設定 X-Config-Token 頭部。但是,您可以省略該頭部,並透過設定與 Spring Cloud Vault 相同的配置屬性,在伺服器中配置身份驗證。要設定的屬性是 spring.cloud.config.server.vault.authentication
。它應設定為支援的身份驗證方法之一。您可能還需要設定特定於您使用的身份驗證方法的其他屬性,使用與 spring.cloud.vault
文件中相同的屬性名稱,但字首更改為 spring.cloud.config.server.vault
。有關更多詳細資訊,請參閱 Spring Cloud Vault 參考指南。
如果您省略 X-Config-Token 頭部並使用伺服器屬性設定身份驗證,則 Config Server 應用程式需要額外依賴 Spring Vault 才能啟用附加的身份驗證選項。有關如何新增該依賴項的資訊,請參閱 Spring Vault 參考指南。 |
多屬性源
使用 Vault 時,您可以為應用程式提供多個屬性源。例如,假設您已將資料寫入 Vault 中的以下路徑:
secret/myApp,dev
secret/myApp
secret/application,dev
secret/application
寫入 secret/application
的屬性可供所有使用 Config Server 的應用程式使用。名為 myApp
的應用程式可以使用寫入 secret/myApp
和 secret/application
的任何屬性。當 myApp
啟用 dev
profile 時,寫入上述所有路徑的屬性都將對其可用,列表中的第一個路徑中的屬性優先於其他路徑。
透過代理訪問後端
配置伺服器可以透過 HTTP 或 HTTPS 代理訪問 Git 或 Vault 後端。此行為透過 proxy.http
和 proxy.https
下的設定為 Git 或 Vault 進行控制。這些設定是針對每個倉庫的,因此如果您使用的是複合環境倉庫,則必須為複合倉庫中的每個後端單獨配置代理設定。如果您使用的網路需要獨立的代理伺服器用於 HTTP 和 HTTPS URL,則可以為單個後端配置 HTTP 和 HTTPS 代理設定:在這種情況下,http
訪問將使用 http
代理,https
訪問將使用 https
代理。此外,您可以使用應用程式和代理之間的代理定義協議指定一個將用於兩種協議的單一代理。
下表描述了 HTTP 和 HTTPS 代理的代理配置屬性。所有這些屬性都必須以 proxy.http
或 proxy.https
為字首。
屬性名稱 | 備註 |
---|---|
host |
代理的主機。 |
port |
訪問代理的埠。 |
nonProxyHosts |
配置伺服器應透過代理外部訪問的任何主機。如果為 |
username |
用於向代理進行身份驗證的使用者名稱。如果為 |
password |
用於向代理進行身份驗證的密碼。如果為 |
以下配置使用 HTTPS 代理訪問 Git 倉庫。
spring:
profiles:
active: git
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
proxy:
https:
host: my-proxy.host.io
password: myproxypassword
port: '3128'
username: myproxyusername
nonProxyHosts: example.com
與所有應用程式共享配置
與所有應用程式共享配置的方法因您採用的方式而異,如下列主題所述:
基於檔案的倉庫
對於基於檔案(git、svn 和 native)的倉庫,檔名為 application*
(application.properties
、application.yml
、application-*.properties
等)的資源會在所有客戶端應用程式之間共享。您可以使用這些檔名的資源來配置全域性預設值,並根據需要由應用程式特定的檔案進行覆蓋。
屬性覆蓋功能也可用於設定全域性預設值,並允許應用程式透過佔位符在本地覆蓋它們。
使用“native” profile(本地檔案系統後端)時,您應該使用一個不在伺服器自身配置中的顯式搜尋位置。否則,預設搜尋位置中的 application* 資源將被移除,因為它們是伺服器的一部分。 |
Vault 伺服器
使用 Vault 作為後端時,您可以透過將配置放置在 secret/application
中來與所有應用程式共享配置。例如,如果您執行以下 Vault 命令,所有使用 Config Server 的應用程式都將擁有 foo
和 baz
屬性:
$ vault write secret/application foo=bar baz=bam
CredHub 伺服器
使用 CredHub 作為後端時,您可以透過將配置放置在 /application/
中或將其放置在應用程式的 default
profile 中來與所有應用程式共享配置。例如,如果您執行以下 CredHub 命令,所有使用 Config Server 的應用程式都將擁有 shared.color1
和 shared.color2
屬性:
credhub set --name "/application/profile/master/shared" --type=json
value: {"shared.color1": "blue", "shared.color": "red"}
credhub set --name "/my-app/default/master/more-shared" --type=json
value: {"shared.word1": "hello", "shared.word2": "world"}
AWS Secrets Manager
使用 AWS Secrets Manager 作為後端時,您可以透過將配置放置在 /application/
中或將其放置在應用程式的 default
profile 中來與所有應用程式共享配置。例如,如果您新增鍵為以下內容的秘密資訊,所有使用 Config Server 的應用程式都將擁有 shared.foo
和 shared.bar
屬性:
secret name = /secret/application-default/
secret value =
{
shared.foo: foo,
shared.bar: bar
}
或
secret name = /secret/application/
secret value =
{
shared.foo: foo,
shared.bar: bar
}
帶標籤的版本
AWS Secrets Manager 倉庫允許以 Git 後端相同的方式儲存帶標籤的配置環境版本。
倉庫實現將 HTTP 資源的 {label}
引數對映到 AWS Secrets Manager 秘密資訊的暫存標籤。要建立帶標籤的秘密資訊,請建立秘密資訊或更新其內容併為其定義一個暫存標籤(有時在 AWS 文件中稱為版本階段)。例如:
$ aws secretsmanager create-secret \
--name /secret/test/ \
--secret-string '{"version":"1"}'
{
"ARN": "arn:aws:secretsmanager:us-east-1:123456789012:secret:/secret/test/-a1b2c3",
"Name": "/secret/test/",
"VersionId": "cd291674-de2f-41de-8f3b-37dbf4880d69"
}
$ aws secretsmanager update-secret-version-stage \
--secret-id /secret/test/ \
--version-stage 1.0.0 \
--move-to-version-id cd291674-de2f-41de-8f3b-37dbf4880d69
{
"ARN": "arn:aws:secretsmanager:us-east-1:123456789012:secret:/secret/test/-a1b2c3",
"Name": "/secret/test/",
}
使用 spring.cloud.config.server.aws-secretsmanager.default-label
屬性設定預設標籤。如果未定義此屬性,後端將使用 AWSCURRENT 作為暫存標籤。
spring:
profiles:
active: aws-secretsmanager
cloud:
config:
server:
aws-secretsmanager:
region: us-east-1
default-label: 1.0.0
請注意,如果未設定預設標籤且請求未定義標籤,倉庫將像停用帶標籤版本支援一樣使用秘密資訊。此外,預設標籤僅在啟用帶標籤支援時使用。否則,定義此屬性毫無意義。
請注意,如果暫存標籤包含斜槓(/
),則 HTTP URL 中的標籤應改為用特殊字串 (_)
指定(以避免與其他 URL 路徑產生歧義),其方式與 Git 後端部分所述相同。
使用 spring.cloud.config.server.aws-secretsmanager.ignore-label
屬性可以忽略 HTTP 資源的 {label}
引數以及 spring.cloud.config.server.aws-secretsmanager.default-label
屬性。倉庫將像停用帶標籤版本支援一樣使用秘密資訊。
spring:
profiles:
active: aws-secretsmanager
cloud:
config:
server:
aws-secretsmanager:
region: us-east-1
ignore-label: true
AWS Parameter Store
使用 AWS Parameter Store 作為後端時,您可以透過將屬性放置在 /application
層次結構中來與所有應用程式共享配置。
例如,如果您新增名稱為以下內容的引數,所有使用 Config Server 的應用程式都將擁有 foo.bar
和 fred.baz
屬性:
/config/application/foo.bar
/config/application-default/fred.baz
JDBC 後端
Spring Cloud Config Server 支援將 JDBC(關係型資料庫)作為配置屬性的後端。您可以透過向 classpath 新增 spring-boot-starter-data-jdbc
並使用 jdbc
profile,或者新增一個型別為 JdbcEnvironmentRepository
的 bean 來啟用此功能。如果您在 classpath 中包含正確的依賴項(有關更多詳細資訊,請參閱使用者指南),Spring Boot 會配置一個數據源。
您可以透過將 spring.cloud.config.server.jdbc.enabled
屬性設定為 false
來停用 JdbcEnvironmentRepository
的自動配置。
資料庫需要有一個名為 PROPERTIES
的表,包含 APPLICATION
、PROFILE
和 LABEL
列(具有通常的 Environment
含義),以及用於 Properties
風格的鍵值對的 KEY
和 VALUE
列。所有欄位在 Java 中都是 String 型別,因此您可以根據需要將其設為任意長度的 VARCHAR
。屬性值的行為方式與來自名為 {application}-{profile}.properties
的 Spring Boot 屬性檔案中的屬性值相同,包括所有加密和解密,這些將作為後處理步驟應用(即,不直接在倉庫實現中)。
用於 JDBC 的預設標籤是 master 。您可以透過設定 spring.cloud.config.server.jdbc.defaultLabel 來更改它。 |
Redis 後端
Spring Cloud Config Server 支援將 Redis 作為配置屬性的後端。您可以透過新增對 Spring Data Redis 的依賴項來啟用此功能。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
以下配置使用 Spring Data RedisTemplate
訪問 Redis。我們可以使用 spring.redis.*
屬性來覆蓋預設連線設定。
spring:
profiles:
active: redis
redis:
host: redis
port: 16379
屬性應作為欄位儲存在雜湊中。雜湊的名稱應與 spring.application.name
屬性相同,或者為 spring.application.name
和 spring.profiles.active[n]
的組合。
HMSET sample-app server.port "8100" sample.topic.name "test" test.property1 "property1"
執行上面可見的命令後,雜湊應該包含以下鍵值對:
HGETALL sample-app { "server.port": "8100", "sample.topic.name": "test", "test.property1": "property1" }
未指定 profile 時,將使用 default 。 |
AWS S3 後端
Spring Cloud Config Server 支援將 AWS S3 作為配置屬性的後端。您可以透過新增對 AWS Java SDK For Amazon S3 的依賴項來啟用此功能。
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
</dependency>
</dependencies>
以下配置使用 AWS S3 客戶端訪問配置檔案。我們可以使用 spring.cloud.config.server.awss3.*
屬性選擇儲存配置的 bucket。
spring:
profiles:
active: awss3
cloud:
config:
server:
awss3:
region: us-east-1
bucket: bucket1
也可以指定 AWS URL 來 覆蓋 S3 服務的標準端點,使用 spring.cloud.config.server.awss3.endpoint
屬性。這支援 S3 的測試版區域以及其他 S3 相容的儲存 API。
使用 預設憑證提供程式鏈查詢憑證。版本化和加密的 bucket 無需進一步配置即可支援。
配置檔案以 {application}-{profile}.properties
、{application}-{profile}.yml
或 {application}-{profile}.json
的形式儲存在您的 bucket 中。可以提供一個可選標籤來指定檔案的目錄路徑。
未指定 profile 時,將使用 default 。 |
AWS Parameter Store 後端
Spring Cloud Config Server 支援將 AWS Parameter Store 作為配置屬性的後端。您可以透過新增對 AWS Java SDK for SSM 的依賴項來啟用此功能。
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>ssm</artifactId>
</dependency>
以下配置使用 AWS SSM 客戶端訪問引數。
spring:
profiles:
active: awsparamstore
cloud:
config:
server:
awsparamstore:
region: eu-west-2
endpoint: https://ssm.eu-west-2.amazonaws.com
origin: aws:parameter:
prefix: /config/service
profile-separator: _
recursive: true
decrypt-values: true
max-results: 5
下表描述了 AWS Parameter Store 配置屬性。
屬性名稱 | 必需 | 預設值 | 備註 |
---|---|---|---|
region |
否 |
AWS Parameter Store 客戶端要使用的區域。如果未明確設定,SDK 會嘗試使用預設區域提供程式鏈來確定要使用的區域。 |
|
endpoint |
否 |
AWS SSM 客戶端入口點的 URL。這可用於為 API 請求指定備用端點。 |
|
origin |
否 |
|
新增到屬性源名稱的字首,用於顯示其來源。 |
prefix |
否 |
|
用於從 AWS Parameter Store 載入的每個屬性在引數層次結構中指示 L1 級別的字首。 |
profile-separator |
否 |
|
將追加的 profile 與上下文名稱分隔開的字串。 |
recursive |
否 |
|
指示檢索層次結構中所有 AWS 引數的標誌。 |
decrypt-values |
否 |
|
指示檢索所有 AWS 引數並解密其值的標誌。 |
max-results |
否 |
|
一次 AWS Parameter Store API 呼叫返回的最大專案數。 |
使用 預設憑證提供程式鏈確定 AWS Parameter Store API 憑證。預設行為是返回最新版本,已支援版本化引數。
|
AWS Secrets Manager 後端
Spring Cloud Config Server 支援將 AWS Secrets Manager 作為配置屬性的後端。您可以透過新增對 AWS Java SDK for Secrets Manager 的依賴項來啟用此功能。
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>secretsmanager</artifactId>
</dependency>
以下配置使用 AWS Secrets Manager 客戶端訪問秘密資訊。
spring:
profiles:
active: awssecretsmanager
cloud:
config:
server:
aws-secretsmanager:
region: us-east-1
endpoint: https://us-east-1.console.aws.amazon.com/
origin: aws:secrets:
prefix: /secret/foo
profileSeparator: _
使用 預設憑證提供程式鏈確定 AWS Secrets Manager API 憑證。
|
CredHub 後端
Spring Cloud Config Server 支援將 CredHub 作為配置屬性的後端。您可以透過新增對 Spring CredHub 的依賴項來啟用此功能。
<dependencies>
<dependency>
<groupId>org.springframework.credhub</groupId>
<artifactId>spring-credhub-starter</artifactId>
</dependency>
</dependencies>
以下配置使用相互 TLS 訪問 CredHub:
spring:
profiles:
active: credhub
cloud:
config:
server:
credhub:
url: https://credhub:8844
屬性應儲存為 JSON,例如:
credhub set --name "/demo-app/default/master/toggles" --type=json
value: {"toggle.button": "blue", "toggle.link": "red"}
credhub set --name "/demo-app/default/master/abs" --type=json
value: {"marketing.enabled": true, "external.enabled": false}
所有名稱為 spring.cloud.config.name=demo-app
的客戶端應用程式都將擁有以下屬性:
{ toggle.button: "blue", toggle.link: "red", marketing.enabled: true, external.enabled: false }
未指定 profile 時將使用 default ,未指定 label 時將使用 master 作為預設值。注意:新增到 application 的值將由所有應用程式共享。 |
OAuth 2.0
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>
</dependencies>
以下配置使用 OAuth 2.0 和 UAA 訪問 CredHub:
spring:
profiles:
active: credhub
cloud:
config:
server:
credhub:
url: https://credhub:8844
oauth2:
registration-id: credhub-client
security:
oauth2:
client:
registration:
credhub-client:
provider: uaa
client-id: credhub_config_server
client-secret: asecret
authorization-grant-type: client_credentials
provider:
uaa:
token-uri: https://uaa:8443/oauth/token
使用的 UAA client-id 應具有 credhub.read 範圍。 |
複合環境倉庫
在某些場景下,您可能希望從多個環境倉庫中拉取配置資料。為此,您可以在配置伺服器的 application properties 或 YAML 檔案中啟用 composite
profile。例如,如果您想從一個 Subversion 倉庫以及兩個 Git 倉庫中拉取配置資料,您可以為配置伺服器設定以下屬性:
spring:
profiles:
active: composite
cloud:
config:
server:
composite:
-
type: svn
uri: file:///path/to/svn/repo
-
type: git
uri: file:///path/to/rex/git/repo
-
type: git
uri: file:///path/to/walter/git/repo
使用此配置,優先順序由倉庫在 composite
鍵下的列出順序決定。在上述示例中,Subversion 倉庫首先列出,因此在 Subversion 倉庫中找到的值將覆蓋在其中一個 Git 倉庫中找到的相同屬性的值。在 rex
Git 倉庫中找到的值將優先於在 walter
Git 倉庫中找到的相同屬性的值。
如果您只想從各自型別不同的倉庫中拉取配置資料,您可以在配置伺服器的 application properties 或 YAML 檔案中啟用相應的 profile,而不是 composite
profile。例如,如果您想從單個 Git 倉庫和單個 HashiCorp Vault 伺服器中拉取配置資料,您可以為配置伺服器設定以下屬性:
spring:
profiles:
active: git, vault
cloud:
config:
server:
git:
uri: file:///path/to/git/repo
order: 2
vault:
host: 127.0.0.1
port: 8200
order: 1
使用此配置,優先順序可以透過 order
屬性確定。您可以使用 order
屬性指定所有倉庫的優先順序。order
屬性的數值越低,優先順序越高。倉庫的優先順序有助於解決包含相同屬性值的倉庫之間的任何潛在衝突。
如果您的複合環境包含 Vault 伺服器,如前例所示,則必須在向配置伺服器發出的每個請求中包含 Vault 令牌。請參閱 Vault 後端。 |
從環境倉庫檢索值時發生的任何型別的失敗都會導致整個複合環境失敗。如果您希望即使某個倉庫失敗也能繼續複合過程,可以將 spring.cloud.config.server.failOnCompositeError 設定為 false 。 |
使用複合環境時,所有倉庫都包含相同的標籤非常重要。如果您的環境類似於前例中的環境,並且您請求帶有 master 標籤的配置資料,但 Subversion 倉庫不包含名為 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
前述示例使所有作為 config client 的應用程式讀取 foo=bar
,與其自身的配置無關。
配置系統不能強制應用程式以任何特定方式使用配置資料。因此,覆蓋不是強制性的。但是,它們確實為 Spring Cloud Config client 提供了有用的預設行為。 |
通常,帶有 ${} 的 Spring 環境佔位符可以透過使用反斜槓(\ )來轉義 $ 或 { 來進行轉義(並在客戶端解析)。例如,\${app.foo:bar} 解析為 bar ,除非應用程式提供了自己的 app.foo 。 |
在 YAML 中,您無需轉義反斜槓本身。但是,在 properties 檔案中,當您在伺服器上配置覆蓋時,您確實需要轉義反斜槓。 |
您可以透過在遠端倉庫中設定 spring.cloud.config.overrideNone=true
標誌(預設值為 false),將所有覆蓋的優先順序更改得更像預設值,允許應用程式在環境變數或系統屬性中提供自己的值。
使用 Bootstrap 覆蓋屬性
如果您啟用配置優先的 bootstrap,您可以透過在 Config Server 使用的外部環境倉庫(例如,Git、Vault、SVN 等)中的應用程式配置中放置兩個屬性,讓客戶端設定覆蓋 Config Server 的配置。
spring.cloud.config.allowOverride=true
spring.cloud.config.overrideNone=true
啟用 Bootstrap 並將這兩個屬性設定為 true 後,您將能夠在客戶端應用程式配置中覆蓋 Config Server 的配置。
使用佔位符覆蓋屬性
一種更簡潔的無需啟用配置優先 bootstrap 即可覆蓋屬性的方法是在來自 Config Server 的配置中使用屬性佔位符。
例如,如果來自 Config Server 的配置包含以下屬性:
hello=${app.hello:Hello From Config Server!}
您可以透過在本地應用程式配置中設定 app.hello
來覆蓋來自 Config Server 的 hello
值:
app.hello=Hello From Application!
使用 Profile 覆蓋屬性
覆蓋來自 Config Server 屬性的最後一種方法是在客戶端應用程式中的 Profile 特定配置檔案中指定它們。
例如,如果您有來自 Config Server 的以下配置:
hello="Hello From Config Server!"
您可以透過在 Profile 特定配置檔案中設定 hello
並啟用該 profile 來在客戶端應用程式中覆蓋 hello
的值。
hello="Hello From Application!"
在上述示例中,您必須啟用 overrides
profile。
健康檢查指示器
Config Server 自帶一個健康檢查指示器,用於檢查配置的 EnvironmentRepository
是否正常工作。預設情況下,它會向 EnvironmentRepository
請求名為 app
、profile 為 default
以及由 EnvironmentRepository
實現提供的預設 label 的應用程式。
您可以配置健康檢查指示器以檢查更多應用程式以及自定義 profile 和自定義 label,如下例所示:
spring:
cloud:
config:
server:
health:
repositories:
myservice:
label: mylabel
myservice-dev:
name: myservice
profiles: development
您可以透過將 management.health.config.enabled
設定為 false
來停用健康檢查指示器。
此外,您可以透過設定屬性 spring.cloud.config.server.health.down-health-status
(預設值為 DOWN
)來提供自定義的 down
狀態。
安全性
您可以以對您有意義的任何方式保護您的 Config Server(從物理網路安全到 OAuth2 bearer 令牌),因為 Spring Security 和 Spring Boot 支援許多安全安排。
要使用預設的 Spring Boot 配置的 HTTP Basic 安全性,請在 classpath 中包含 Spring Security(例如,透過 spring-boot-starter-security
)。預設使用者名稱為 user
,密碼是隨機生成的。隨機密碼在實踐中用途不大,因此我們建議您配置密碼(透過設定 spring.security.user.password
)並對其進行加密(有關如何執行此操作的說明,請參閱下文)。
Actuator 和安全性
一些平臺配置健康檢查或類似功能,並指向 /actuator/health 或其他 actuator 端點。如果 actuator 不是 Config Server 的依賴項,則對 /actuator/ 的請求將匹配 Config Server API /{application}/{label} ,可能洩露敏感資訊。在這種情況下,請務必新增 spring-boot-starter-actuator 依賴項,並配置使用者,使呼叫 /actuator/ 的使用者無法訪問 /{application}/{label} 的 Config Server API。 |
加密和解密
要使用加密和解密功能,您需要在 JVM 中安裝完整強度的 JCE(預設不包含)。您可以從 Oracle 下載“Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files”,並按照安裝說明進行操作(基本上,您需要將 JRE lib/security 目錄中的兩個策略檔案替換為您下載的檔案)。 |
如果遠端屬性源包含加密內容(值以 {cipher}
開頭),它們將在透過 HTTP 傳送給客戶端之前被解密。這種設定的主要優點是屬性值在“靜止”時(例如,在 git 倉庫中)無需明文。如果某個值無法解密,它將從屬性源中移除,並新增一個具有相同 key 但字首為 invalid
且值為“不適用”(通常為 <n/a>
)的附加屬性。這主要是為了防止密文被用作密碼並意外洩露。
如果您為 config client 應用程式設定遠端配置倉庫,它可能包含類似以下的 application.yml
:
spring:
datasource:
username: dbuser
password: '{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ'
application.properties
檔案中的加密值不得用引號括起來。否則,該值將不會被解密。以下示例顯示了有效的格式:
spring.datasource.username: dbuser spring.datasource.password: {cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ
您可以安全地將此明文推送到共享 git 倉庫,秘密密碼將得到保護。
伺服器還暴露了 /encrypt
和 /decrypt
端點(假定這些端點是安全的,並且僅由授權代理訪問)。如果您編輯遠端配置檔案,可以使用 Config Server 透過向 /encrypt
端點發送 POST 請求來加密值,如下例所示:
$ curl localhost:8888/encrypt -s -d mysecret 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
如果您使用 curl 進行測試,請使用 --data-urlencode (代替 -d )並在要加密的值前加上 = (curl 需要這樣),或設定顯式 Content-Type: text/plain 以確保 curl 在存在特殊字元('+' 特別棘手)時正確編碼資料。 |
確保不要將任何 curl 命令統計資訊包含在加密值中,這就是示例使用 -s 選項來靜默它們的原因。將值輸出到檔案可以幫助避免此問題。 |
反向操作也透過 /decrypt
可用(前提是伺服器配置了對稱 key 或完整的金鑰對),如下例所示:
$ curl localhost:8888/decrypt -s -d 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda mysecret
將加密值加上 {cipher}
字首,然後將其放入 YAML 或 properties 檔案中,再提交併推送到遠端(可能不安全)儲存。
/encrypt
和 /decrypt
端點也接受 /*/{application}/{profiles}
形式的路徑,當客戶端呼叫主環境資源時,可用於按應用程式(名稱)和按 profile 控制加密。
要以這種粒度控制加密,您還必須提供一個型別為 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+...
--key 引數是必需的(儘管有 -- 字首)。 |
金鑰管理
Config Server 可以使用對稱(共享)金鑰或非對稱金鑰(RSA 金鑰對)。非對稱金鑰在安全性方面更優越,但使用對稱金鑰通常更方便,因為在 application.properties
中只需要配置一個屬性值。
要配置對稱金鑰,您需要將 encrypt.key
設定為一個秘密字串(或使用 ENCRYPT_KEY
環境變數以避免將其暴露在純文字配置檔案中)。
如果您在類路徑中包含 spring-cloud-starter-bootstrap 或將 spring.cloud.bootstrap.enabled=true 設定為系統屬性,則需要在 bootstrap.properties 中設定 encrypt.key 。 |
您不能使用 encrypt.key 配置非對稱金鑰。 |
要配置非對稱金鑰,請使用金鑰庫(例如,透過 JDK 自帶的 keytool
工具建立)。金鑰庫屬性是 encrypt.keyStore.*
,其中 *
等於
屬性 | 描述 |
---|---|
|
包含一個 |
|
儲存用於解鎖金鑰庫的密碼 |
|
標識要使用的金鑰庫中的金鑰 |
|
要建立的 KeyStore 型別。預設為 |
加密使用公鑰完成,解密需要私鑰。因此,原則上,如果您只想加密(並準備好自己在本地用私鑰解密),您可以在伺服器中僅配置公鑰。實際上,您可能不想在本地解密,因為它將金鑰管理過程分散到所有客戶端,而不是集中在伺服器中。另一方面,如果您的配置伺服器相對不安全,並且只有少數客戶端需要加密屬性,那麼這是一個有用的選項。
建立測試金鑰庫
要建立用於測試的金鑰庫,可以使用類似於以下內容的命令
$ 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
使用 JDK 11 或更高版本時,在使用上述命令時可能會收到以下警告。在這種情況下,您可能需要確保 keypass 和 storepass 的值匹配。 |
Warning: Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified -keypass value.
將 server.jks
檔案放在類路徑中(例如),然後在 Config Server 的 bootstrap.yml
中,建立以下設定
encrypt:
keyStore:
location: classpath:/server.jks
password: letmein
alias: mytestkey
secret: changeme
使用多個金鑰和金鑰輪換
除了加密屬性值中的 {cipher}
字首之外,Config Server 還會查詢在(Base64 編碼的)密文開始之前的零個或多個 {name:value}
字首。這些金鑰被傳遞給 TextEncryptorLocator
,它可以執行所需的任何邏輯來為密文定位一個 TextEncryptor
。如果您配置了金鑰庫(encrypt.keystore.location
),預設的定位器會查詢由 key
字首提供的別名金鑰,其密文類似於
foo:
bar: `{cipher}{key:testkey}...`
定位器查詢名為 "testkey" 的金鑰。也可以在字首中使用 {secret:…}
值來提供秘密。但是,如果未提供秘密,預設是使用金鑰庫密碼(這是您構建金鑰庫且未指定秘密時獲得的結果)。如果您提供了秘密,則還應該使用自定義的 SecretLocator
來加密秘密。
當金鑰僅用於加密少量配置資料(即未在其他地方使用)時,從加密角度來看,金鑰輪換幾乎沒有必要。但是,您可能偶爾需要更改金鑰(例如,在安全漏洞事件中)。在這種情況下,所有客戶端都需要更改其原始碼配置檔案(例如,在 git 中),並在所有密文中使用新的 {key:…}
字首。請注意,客戶端需要首先檢查金鑰別名在 Config Server 金鑰庫中是否可用。
如果您希望 Config Server 處理所有加密和解密,{name:value} 字首也可以作為純文字新增到傳送到 /encrypt 端點的請求體中。 |
提供加密屬性
有時您希望客戶端在本地解密配置,而不是在伺服器中進行。在這種情況下,如果您提供了用於定位金鑰的 encrypt.*
配置,您仍然可以擁有 /encrypt
和 /decrypt
端點,但您需要在 bootstrap.[yml|properties]
中明確關閉對出站屬性的解密,方法是設定 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 或屬性格式的替代表示)之外,您的應用程式可能還需要根據其環境定製的通用純文字配置檔案。Config Server 透過 /{application}/{profile}/{label}/{path}
的額外端點提供這些檔案,其中 application
、profile
和 label
與常規環境端點具有相同的含義,而 path
是指向檔名的路徑(例如 log.xml
)。此端點的原始檔的查詢方式與環境端點相同。屬性檔案和 YAML 檔案使用相同的搜尋路徑。但是,不會聚合所有匹配的資源,只會返回第一個匹配的資源。
找到資源後,將使用提供的應用程式名稱、配置檔案和標籤的有效 Environment
來解析正常格式(${…}
)的佔位符。透過這種方式,資源端點與環境端點緊密整合。
與環境配置的原始檔一樣,profile 用於解析檔名。因此,如果您想要一個特定於配置檔案的檔案,可以透過一個名為 logback-development.xml 的檔案來解析 /*/development/*/logback.xml (優先於 logback.xml )。 |
如果您不想提供 label 並讓伺服器使用預設標籤,您可以提供 useDefaultLabel 請求引數。因此,前面關於 default 配置檔案的示例可以是 /sample/default/nginx.conf?useDefaultLabel 。 |
目前,Spring Cloud Config 可以為 git、SVN、原生後端和 AWS S3 提供純文字。對 git、SVN 和原生後端的支援是相同的。AWS S3 的工作方式略有不同。以下部分顯示了它們各自的工作方式
提供二進位制檔案
為了從配置伺服器提供二進位制檔案,您需要傳送一個 Accept
頭部,其值為 application/octet-stream
。
Git、SVN 和原生後端
考慮以下針對 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
/sample/default/master/nginx.conf
資源可能如下所示
server {
listen 80;
server_name example.com;
}
/sample/development/master/nginx.conf
可能如下所示
server {
listen 80;
server_name develop.com;
}
AWS S3
要啟用為 AWS S3 提供純文字,Config Server 應用程式需要包含對 io.awspring.cloud:spring-cloud-aws-context
的依賴。有關如何設定該依賴項的詳細資訊,請參閱 Spring Cloud AWS Reference Guide。此外,在使用 Spring Cloud AWS 和 Spring Boot 時,包含 自動配置依賴項 會很有用。然後,您需要配置 Spring Cloud AWS,如 Spring Cloud AWS Reference Guide 中所述。
解密純文字
預設情況下,純文字檔案中的加密值不會被解密。為了啟用純文字檔案的解密,請在 bootstrap.[yml|properties]
中設定 spring.cloud.config.server.encrypt.enabled=true
和 spring.cloud.config.server.encrypt.plainTextEncrypt=true
解密純文字檔案僅支援 YAML、JSON 和 properties 副檔名。 |
如果啟用了此功能,並且請求了不受支援的副檔名,則檔案中的任何加密值都不會被解密。
嵌入式 Config Server
Config Server 作為獨立應用程式執行效果最佳。但是,如有需要,您可以將其嵌入到另一個應用程式中。為此,請使用 @EnableConfigServer
註解。在這種情況下,一個名為 spring.cloud.config.server.bootstrap
的可選屬性可能很有用。它是一個標誌,指示伺服器是否應從其自己的遠端倉庫配置自身。預設情況下,此標誌是關閉的,因為它可能會延遲啟動。但是,當嵌入在另一個應用程式中時,以與任何其他應用程式相同的方式初始化是合理的。將 spring.cloud.config.server.bootstrap
設定為 true
時,您還必須使用 組合環境倉庫配置。例如
spring:
application:
name: configserver
profiles:
active: composite
cloud:
config:
server:
composite:
- type: native
search-locations: ${HOME}/Desktop/config
bootstrap: true
如果您使用 bootstrap 標誌,則需要在 bootstrap.yml 中配置 Config Server 的名稱和倉庫 URI。 |
要更改伺服器端點的位置,您可以(可選)設定 spring.cloud.config.server.prefix
(例如,/config
),以在某個字首下提供資源。此字首應以 /
開頭,但不以 /
結尾。它應用於 Config Server 中的 @RequestMappings
(即在 Spring Boot 的 server.servletPath
和 server.contextPath
字首之下)。
如果您想直接從後端倉庫讀取應用程式的配置(而不是從配置伺服器),您基本上需要一個沒有端點的嵌入式配置伺服器。您可以透過不使用 @EnableConfigServer
註解來完全關閉端點(設定 spring.cloud.config.server.bootstrap=true
)。
推送通知和 Spring Cloud Bus
許多原始碼倉庫提供商(例如 Github、Gitlab、Gitea、Gitee、Gogs 或 Bitbucket)透過 webhook 通知您倉庫的更改。您可以透過提供商的使用者介面將 webhook 配置為一個 URL 和一組您感興趣的事件。例如,Github 使用 POST 請求到 webhook,請求體是一個包含提交列表的 JSON,並且頭部 (X-Github-Event
) 設定為 push
。如果您新增對 spring-cloud-config-monitor
庫的依賴,並在 Config Server 中啟用 Spring Cloud Bus,則會啟用 /monitor
端點。
當 webhook 被啟用時,Config Server 會發送一個定向到它認為可能已更改的應用程式的 RefreshRemoteApplicationEvent
。更改檢測可以進行策略化。但是,預設情況下,它查詢與應用程式名稱匹配的檔案中的更改(例如,foo.properties
定向到 foo
應用程式,而 application.properties
定向到所有應用程式)。當您想要覆蓋此行為時使用的策略是 PropertyPathNotificationExtractor
,它接受請求頭部和請求體作為引數,並返回一個已更改的檔案路徑列表。
預設配置與 Github、Gitlab、Gitea、Gitee、Gogs 或 Bitbucket 開箱即用。除了來自 Github、Gitlab、Gitee 或 Bitbucket 的 JSON 通知外,您還可以透過向 /monitor
傳送 POST 請求並使用格式為 path={application}
的表單編碼請求體引數來觸發更改通知。這樣做會將通知廣播到與 {application}
模式匹配的應用程式(該模式可以包含萬用字元)。
只有當 Config Server 和客戶端應用程式都激活了 spring-cloud-bus 時,RefreshRemoteApplicationEvent 才會傳輸。 |
預設配置還會檢測本地 git 倉庫中的檔案系統更改。在這種情況下,不使用 webhook。但是,只要您編輯配置檔案,就會廣播重新整理通知。 |
AOT 和 Native Image 支援
自 4.0.0
起,Spring Cloud Config Server 支援 Spring AOT 轉換。然而,目前尚不支援 GraalVM Native Image。實現 Native Image 支援被 graal#5134 阻止,並且可能需要完成 https://github.com/graalvm/taming-build-time-initialization 上的工作才能修復。
Spring Cloud Config Client
Spring Boot 應用程式可以立即利用 Spring Config Server(或應用程式開發人員提供的其他外部屬性源)。它還獲得了一些與 Environment
更改事件相關的額外有用功能。
Spring Boot 配置資料匯入
Spring Boot 2.4 引入了一種透過 spring.config.import
屬性匯入配置資料的新方法。這現在是繫結到 Config Server 的預設方式。
要選擇性地連線到配置伺服器,請在 application.properties 中進行如下設定
spring.config.import=optional:configserver:
這將連線到預設位置 "https://:8888" 的 Config Server。移除 optional:
字首將導致 Config Client 在無法連線到 Config Server 時啟動失敗。要更改 Config Server 的位置,可以設定 spring.cloud.config.uri
或將 URL 新增到 spring.config.import
語句中,例如 spring.config.import=optional:configserver:http://myhost:8888
。import 屬性中的位置優先於 uri 屬性。
Spring Boot 配置資料分兩步解析配置。首先,它使用 default
profile 載入所有配置。這允許 Spring Boot 收集所有可能啟用任何其他 profile 的配置。收集到所有啟用的 profile 後,它將為活動的 profile 載入任何額外的配置。因此,您可能會看到向 Spring Cloud Config Server 發出多個請求來獲取配置。這是正常的,是 Spring Boot 使用 spring.config.import
載入配置的方式所帶來的副作用。在 Spring Cloud Config 的早期版本中,只發出一個請求,但這表示您無法從 Config Server 獲取的配置中啟用 profile。現在,只需使用 'default' profile 發出的額外請求使這成為可能。
對於透過 spring.config.import 匯入的 Spring Boot 配置資料方法,不需要 bootstrap 檔案(properties 或 yaml)。 |
Config First Bootstrap
要使用連線到 Config Server 的傳統 bootstrap 方式,必須透過屬性或 spring-cloud-starter-bootstrap
Starter 啟用 bootstrap。該屬性為 spring.cloud.bootstrap.enabled=true
。它必須設定為系統屬性或環境變數。啟用 bootstrap 後,類路徑中包含 Spring Cloud Config Client 的任何應用程式將按如下方式連線到 Config Server:當 config client 啟動時,它會繫結到 Config Server(透過 spring.cloud.config.uri
bootstrap 配置屬性),並使用遠端屬性源初始化 Spring Environment
。
這種行為的最終結果是,所有希望使用 Config Server 的客戶端應用程式都需要一個 bootstrap.yml
(或環境變數),並在其中設定 spring.cloud.config.uri
的伺服器地址(預設為 "https://:8888")。
Discovery First Lookup
除非您使用 Config First Bootstrap,否則您需要在配置屬性中包含帶有 optional: 字首的 spring.config.import 屬性。例如,spring.config.import=optional:configserver: 。 |
如果您使用 DiscoveryClient
實現,例如 Spring Cloud Netflix 和 Eureka 服務發現或 Spring Cloud Consul,您可以讓 Config Server 向 Discovery Service 註冊。
如果您更喜歡使用 DiscoveryClient
來定位 Config Server,可以透過設定 spring.cloud.config.discovery.enabled=true
來實現(預設為 false
)。例如,使用 Spring Cloud Netflix,您需要定義 Eureka 伺服器地址(例如,在 eureka.client.serviceUrl.defaultZone
中)。使用此選項的代價是啟動時需要額外進行一次網路往返以定位服務註冊。好處是,只要 Discovery Service 是固定的,Config Server 就可以更改其座標。預設服務 ID 是 configserver
,但您可以在客戶端透過設定 spring.cloud.config.discovery.serviceId
來更改它(在伺服器端,可以使用服務通常的方式更改,例如設定 spring.application.name
)。
Discovery Client 實現都支援某種元資料對映(例如,對於 Eureka,我們有 eureka.instance.metadataMap
)。Config Server 的某些附加屬性可能需要在其服務註冊元資料中配置,以便客戶端能夠正確連線。如果 Config Server 使用 HTTP Basic 進行安全保護,您可以將憑據配置為 user
和 password
。此外,如果 Config Server 有上下文路徑,您可以設定 configPath
。例如,以下 YAML 檔案適用於作為 Eureka 客戶端的 Config Server
eureka:
instance:
...
metadataMap:
user: osufhalskjrtl
password: lviuhlszvaorhvlo5847
configPath: /config
使用 Eureka 和 WebClient 的 Discovery First Bootstrap
如果您使用 Spring Cloud Netflix 中的 Eureka DiscoveryClient
,並且還想使用 WebClient
代替 Jersey 或 RestTemplate
,您需要在類路徑中包含 WebClient
,並設定 eureka.client.webclient.enabled=true
。
Config Client 快速失敗
在某些情況下,如果您無法連線到 Config Server,您可能希望服務啟動失敗。如果這是期望的行為,請將 bootstrap 配置屬性 spring.cloud.config.fail-fast=true
設定為使客戶端丟擲 Exception 並停止。
要使用 spring.config.import 獲得類似的功能,只需省略 optional: 字首。 |
Config Client 重試
如果您期望 Config Server 在應用程式啟動時可能偶爾不可用,您可以在失敗後讓它繼續嘗試。首先,您需要設定 spring.cloud.config.fail-fast=true
。然後,您需要在類路徑中新增 spring-retry
和 spring-boot-starter-aop
。預設行為是重試六次,初始退避間隔為 1000ms,後續退避的指數乘數為 1.1。您可以透過設定 spring.cloud.config.retry.*
配置屬性來配置這些屬性(以及其他屬性)。要使用隨機指數退避策略,請將 spring.cloud.config.retry.useRandomPolicy
設定為 true
。
要完全控制重試行為並使用舊版 bootstrap,請新增一個型別為 RetryOperationsInterceptor 且 ID 為 configServerRetryInterceptor 的 @Bean 。Spring Retry 提供了一個支援建立此類 Bean 的 RetryInterceptorBuilder 。 |
使用 spring.config.import 的 Config Client 重試
重試功能與 Spring Boot 的 spring.config.import
語句和正常屬性一起使用。但是,如果 import 語句位於 profile 中,例如 application-prod.properties
,則需要另一種方式來配置重試。配置需要作為 URL 引數放置在 import 語句上。
spring.config.import=configserver:http://configserver.example.com?fail-fast=true&max-attempts=10&max-interval=1500&multiplier=1.2&initial-interval=1100"
這將設定 spring.cloud.config.fail-fast=true
(請注意上面缺少字首)和所有可用的 spring.cloud.config.retry.*
配置屬性。
定位遠端配置資源
Config Service 從 /{application}/{profile}/{label}
提供屬性源,其中客戶端應用程式中的預設繫結如下
-
"application" =
${spring.application.name}
-
"profile" =
${spring.profiles.active}
(實際上是Environment.getActiveProfiles()
) -
"label" = "master"
設定屬性 `${spring.application.name}` 時,不要在您的應用程式名稱前面加上保留字 `application-`,以免出現無法解析正確屬性源的問題。 |
您可以透過設定 spring.cloud.config.*
來覆蓋所有這些(其中 *
是 name
、profile
或 label
)。label
對於回滾到以前版本的配置很有用。對於預設的 Config Server 實現,它可以是 git label、分支名稱或提交 ID。Label 也可以以逗號分隔的列表形式提供。在這種情況下,列表中的項會逐個嘗試,直到成功。這種行為在處理 feature 分支時很有用。例如,您可能希望將配置標籤與您的分支對齊,但使其成為可選的(在這種情況下,使用 spring.cloud.config.label=myfeature,develop
)。
為 Config Server 指定多個 URL
當您部署了多個 Config Server 例項,並期望有時一個或多個例項不可用或無法響應請求(例如 Git 伺服器宕機)時,為了確保高可用性,您可以指定多個 URL(在 spring.cloud.config.uri
屬性下以逗號分隔列表形式),或者讓所有例項在像 Eureka 這樣的服務註冊中心註冊(如果使用 Discovery-First Bootstrap 模式)。
在 spring.cloud.config.uri
下列出的 URL 會按照列表中的順序嘗試。預設情況下,Config Client 會嘗試從每個 URL 獲取屬性,直到嘗試成功,以確保高可用性。
但是,如果您只想在 Config Server 未執行時(即應用程式已退出)或發生連線超時時確保高可用性,請將 spring.cloud.config.multiple-uri-strategy
設定為 connection-timeout-only
。(spring.cloud.config.multiple-uri-strategy
的預設值為 always
。)例如,如果 Config Server 返回 500(內部伺服器錯誤)響應,或者 Config Client 從 Config Server 收到 401(由於憑據錯誤或其他原因),則 Config Client 不會嘗試從其他 URL 獲取屬性。400 錯誤(可能除了 404)表示使用者問題,而不是可用性問題。請注意,如果 Config Server 設定為使用 Git 伺服器,並且對 Git 伺服器的呼叫失敗,則可能會發生 404 錯誤。
可以在單個 spring.config.import
鍵下指定多個位置,而不是使用 spring.cloud.config.uri
。位置將按定義的順序處理,後面的匯入優先。但是,如果 spring.cloud.config.fail-fast
為 true
,則如果第一次呼叫 Config Server 因任何原因失敗,Config Client 將會失敗。如果 fail-fast
為 false
,它將嘗試所有 URL,直到有一個呼叫成功,無論失敗原因是什麼。(在使用 spring.config.import
指定 URL 時,spring.cloud.config.multiple-uri-strategy
不適用。)
如果您在 Config Server 上使用 HTTP basic 安全性,目前只有當您在 spring.cloud.config.uri
屬性下指定的每個 URL 中嵌入憑據時,才支援每個 Config Server 的身份驗證憑據。如果您使用任何其他型別的安全機制,則(目前)不支援每個 Config Server 的身份驗證和授權。
配置超時
如果要配置超時閾值
-
讀超時可以使用屬性
spring.cloud.config.request-read-timeout
進行配置。 -
連線超時可以使用屬性
spring.cloud.config.request-connect-timeout
進行配置。
安全性
如果您在伺服器上使用 HTTP Basic 安全性,客戶端需要知道密碼(如果不是預設使用者名稱,則還需要使用者名稱)。您可以透過配置伺服器 URI 或透過單獨的使用者名稱和密碼屬性來指定使用者名稱和密碼,如以下示例所示
spring:
cloud:
config:
uri: https://user:[email protected]
以下示例顯示了傳遞相同資訊的另一種方法
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
的使用者提供服務中均可工作。
spring:
cloud:
config:
uri: ${vcap.services.configserver.credentials.uri:http://user:password@localhost:8888}
如果配置伺服器需要客戶端 TLS 證書,您可以透過屬性配置客戶端 TLS 證書和信任儲存,如下例所示
spring:
cloud:
config:
uri: https://myconfig.myconfig.com
tls:
enabled: true
key-store: <path-of-key-store>
key-store-type: PKCS12
key-store-password: <key-store-password>
key-password: <key-password>
trust-store: <path-of-trust-store>
trust-store-type: PKCS12
trust-store-password: <trust-store-password>
spring.cloud.config.tls.enabled
需要設定為 true 以啟用配置客戶端 TLS。省略 spring.cloud.config.tls.trust-store
時,將使用 JVM 預設信任儲存。spring.cloud.config.tls.key-store-type
和 spring.cloud.config.tls.trust-store-type
的預設值是 PKCS12。省略密碼屬性時,假定密碼為空。
如果您使用其他形式的安全機制,您可能需要向 ConfigServicePropertySourceLocator
提供一個 RestTemplate
(例如,在引導上下文 (bootstrap context) 中獲取並注入它)。
健康指示器
Config Client 提供了一個 Spring Boot 健康指示器,它嘗試從 Config Server 載入配置。可以透過設定 health.config.enabled=false
來停用健康指示器。出於效能原因,響應也會被快取。預設的快取存活時間為 5 分鐘。要更改此值,請設定 health.config.time-to-live
屬性(以毫秒為單位)。
提供自定義 RestTemplate
在某些情況下,您可能需要自定義客戶端向配置伺服器發出的請求。通常,這涉及傳遞特殊的 Authorization
頭部資訊以對伺服器的請求進行身份驗證。
使用 Config Data 提供自定義 RestTemplate
在使用 Config Data 時提供自定義 RestTemplate
-
建立一個實現
BootstrapRegistryInitializer
的類CustomBootstrapRegistryInitializer.javapublic class CustomBootstrapRegistryInitializer implements BootstrapRegistryInitializer { @Override public void initialize(BootstrapRegistry registry) { registry.register(RestTemplate.class, context -> { RestTemplate restTemplate = new RestTemplate(); // Customize RestTemplate here return restTemplate; }); } }
-
在
resources/META-INF
中,建立一個名為spring.factories
的檔案並指定您的自定義配置,如下例所示spring.factoriesorg.springframework.boot.BootstrapRegistryInitializer=com.my.config.client.CustomBootstrapRegistryInitializer
使用 Bootstrap 提供自定義 RestTemplate
在使用 Bootstrap 時提供自定義 RestTemplate
-
建立一個新的配置 bean,其中包含
PropertySourceLocator
的實現,如下例所示CustomConfigServiceBootstrapConfiguration.java@Configuration public class CustomConfigServiceBootstrapConfiguration { @Bean public ConfigServicePropertySourceLocator configServicePropertySourceLocator() { ConfigClientProperties clientProperties = configClientProperties(); ConfigServicePropertySourceLocator configServicePropertySourceLocator = new ConfigServicePropertySourceLocator(clientProperties); configServicePropertySourceLocator.setRestTemplate(customRestTemplate(clientProperties)); return configServicePropertySourceLocator; } }
對於新增 Authorization
頭部資訊的簡化方法,可以使用spring.cloud.config.headers.*
屬性代替。 -
在
resources/META-INF
中,建立一個名為spring.factories
的檔案並指定您的自定義配置,如下例所示spring.factoriesorg.springframework.cloud.bootstrap.BootstrapConfiguration = com.my.config.client.CustomConfigServiceBootstrapConfiguration
Vault
當使用 Vault 作為配置伺服器的後端時,客戶端需要提供一個令牌,供伺服器從 Vault 中檢索值。這個令牌可以透過在 bootstrap.yml
中設定 spring.cloud.config.token
來在客戶端中提供,如下例所示
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
。
AOT 和 Native Image 支援
自 4.0.0
起,Spring Cloud Config Client 支援 Spring AOT 轉換和 GraalVM native images。
AOT 和 native image 支援不適用於配置優先引導(使用 spring.config.use-legacy-processing=true )。 |
Native image 不支援 Refresh scope。如果您打算將 Config Client 應用程式作為 native image 執行,請務必將 spring.cloud.refresh.enabled 屬性設定為 false 。 |
在構建包含 Spring Cloud Config Client 的專案時,您必須確保它連線到的配置資料來源(例如,Spring Cloud Config Server、Consul、Zookeeper、Vault 等)可用。例如,如果您從 Spring Cloud Config Server 檢索配置資料,請確保其例項正在執行並可在 Config Client 設定中指示的埠上可用。這是必要的,因為應用程式上下文在構建時被最佳化,並且需要解析目標環境。 |
由於在 AOT 和 Native 模式下,配置在構建時被處理並且上下文被最佳化,任何會影響 bean 建立的屬性(例如在引導上下文 (bootstrap context) 中使用的屬性)在構建時和執行時應設定為相同的值,以避免意外行為。 |
由於 Config Client 在從 native image 啟動時連線到正在執行的資料來源(例如 Config Server),快速啟動時間將會因網路通訊所需的時間而減慢。 |
附錄
可觀測性元資料
可觀測性 - 指標
您可以在下方找到此專案宣告的所有指標列表。
環境倉庫 (Environment Repository)
圍繞 EnvironmentRepository 建立的觀測。
指標名稱 spring.cloud.config.environment.find
(由約定類 org.springframework.cloud.config.server.environment.ObservationEnvironmentRepositoryObservationConvention
定義)。型別 timer
。
指標名稱 spring.cloud.config.environment.find.active
(由約定類 org.springframework.cloud.config.server.environment.ObservationEnvironmentRepositoryObservationConvention
定義)。型別 long task timer
。
在開始觀測後新增的 KeyValue 可能在 *.active 指標中缺失。 |
Micrometer 內部使用 nanoseconds 作為基本單位。然而,每個後端確定實際的基本單位。(即 Prometheus 使用 seconds) |
封閉類的完全限定名 org.springframework.cloud.config.server.environment.DocumentedConfigObservation
。
所有標籤必須以 spring.cloud.config.environment 字首開頭! |
名稱 |
描述 |
|
正在查詢屬性的應用程式名稱。 |
|
EnvironmentRepository 的實現。 |
|
正在查詢屬性的標籤。 |
|
正在查詢屬性的應用程式名稱。 |
可觀測性 - Span
您可以在下方找到此專案宣告的所有 Span 列表。
環境倉庫 Span
圍繞 EnvironmentRepository 建立的觀測。
Span 名稱 spring.cloud.config.environment.find
(由約定類 org.springframework.cloud.config.server.environment.ObservationEnvironmentRepositoryObservationConvention
定義)。
封閉類的完全限定名 org.springframework.cloud.config.server.environment.DocumentedConfigObservation
。
所有標籤必須以 spring.cloud.config.environment 字首開頭! |
名稱 |
描述 |
|
正在查詢屬性的應用程式名稱。 |
|
EnvironmentRepository 的實現。 |
|
正在查詢屬性的標籤。 |
|
正在查詢屬性的應用程式名稱。 |