4.0.5
Spring Cloud Config 為分散式系統中的外部化配置提供伺服器端和客戶端支援。透過配置伺服器,您可以集中管理所有環境中應用程式的外部屬性。客戶端和伺服器上的概念都與 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 作為 spring.config.name 注入到 SpringApplication 中(在常規 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 starter 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- 作為應用程式名稱的字首,以防止解析正確的屬性源時出現問題。 |
配置伺服器屬性在 /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>/<檔名> 的屬性源包含 foo 屬性,其值為 bar。
| 屬性源名稱中的 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 和屬性檔案的 git 倉庫。
在 Windows 上,如果檔案 URL 是絕對路徑並帶有驅動器字首(例如,file:///${user.home}/config-repo),則需要在檔案 URL 中多加一個 “/”。 |
|
以下列表顯示了在上述示例中建立 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 應用程式,從 spring.config.name 等於 {application} 引數和 spring.profiles.active 等於 {profiles} 引數的配置檔案中載入配置。配置檔案的優先順序規則也與常規 Spring Boot 應用程式中的相同:活動配置檔案優先於預設值,如果有多個配置檔案,則最後一個勝出(類似於向 Map 中新增條目)。
以下示例客戶端應用程式具有此引導配置:
spring:
application:
name: foo
profiles:
active: dev,mysql
(與 Spring Boot 應用程式一樣,這些屬性也可以透過環境變數或命令列引數設定)。
如果倉庫是基於檔案的,伺服器會從 application.yml(所有客戶端共享)和 foo.yml(foo.yml 優先)建立 Environment。如果 YAML 檔案中包含指向 Spring 配置檔案的文件,則這些配置檔案將以更高的優先順序應用(按列出的配置檔案順序)。如果存在特定於配置檔案的 YAML(或屬性)檔案,則這些檔案也將以比預設值更高的優先順序應用。更高的優先順序意味著在 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 支援帶有 {application} 和 {profile} 佔位符的 git 倉庫 URL(如果需要,還可以使用 {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 陣列(或屬性檔案中的 [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,*"] 等的快捷方式)。這在例如您需要在本地執行“development”配置檔案但又在遠端執行“cloud”配置檔案的情況下很常見。 |
每個倉庫還可以選擇將配置檔案儲存在子目錄中,並且可以指定搜尋這些目錄的模式作為 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 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 也應該開箱即用。重要的是,Git 伺服器的條目必須存在於 ~/.ssh/known_hosts 檔案中,並且必須採用 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 要求 RSA 金鑰為 PEM 格式。以下是 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 不在您的類路徑中,則不會建立 AWS Code Commit 憑證提供程式,無論 git 伺服器 URI 如何。 |
使用 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 不在您的類路徑中,則不會建立 Google Cloud Source 憑證提供程式,無論 git 伺服器 URI 如何。 |
使用屬性的 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 倉庫,這樣 Spring Cloud Config Server 無法從遠端倉庫更新本地副本。
為了解決這個問題,有一個 force-pull 屬性,它使 Spring Cloud Config Server 在本地副本髒時強制從遠端倉庫拉取,如以下示例所示:
spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
force-pull: true
如果您有多個倉庫配置,您可以為每個倉庫配置 force-pull 屬性,如以下示例所示:
spring:
cloud:
config:
server:
git:
uri: https://git/common/config-repo.git
force-pull: true
repos:
team-a:
pattern: team-a-*
uri: 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-<隨機 ID>。某些作業系統會定期清理臨時目錄。這可能導致意外行為,例如屬性丟失。為了避免此問題,透過設定 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 |
假 |
超時 |
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 屬性。
當您的配置伺服器執行時,您可以向伺服器發出 HTTP 請求以從 Vault 後端檢索值。為此,您需要一個 Vault 伺服器的令牌。
首先,在 Vault 中放置一些資料,如以下示例所示:
$ vault kv put secret/application foo=bar baz=bam
$ vault kv put secret/myapp foo=myappsbar
其次,向您的配置伺服器發出 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 的屬性可供所有使用配置伺服器的應用程式使用。名為 myApp 的應用程式將可使用寫入 secret/myApp 和 secret/application 的任何屬性。當 myApp 啟用了 dev 配置檔案時,上述所有路徑中寫入的屬性都將可用,其中列表中第一個路徑中的屬性優先於其他屬性。
透過代理訪問後端
配置伺服器可以透過 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”配置檔案(本地檔案系統後端),您應該使用一個明確的搜尋位置,該位置不屬於伺服器自己的配置。否則,預設搜尋位置中的 application* 資源將被刪除,因為它們是伺服器的一部分。 |
Vault 伺服器
當使用 Vault 作為後端時,您可以透過將配置放置在 secret/application 中來與所有應用程式共享配置。例如,如果您執行以下 Vault 命令,所有使用配置伺服器的應用程式都將可使用屬性 foo 和 baz:
$ vault write secret/application foo=bar baz=bam
CredHub 伺服器
當使用 CredHub 作為後端時,您可以透過將配置放置在 /application/ 中或將其放置在應用程式的 default 配置檔案中來與所有應用程式共享配置。例如,如果您執行以下 CredHub 命令,所有使用配置伺服器的應用程式都將可使用屬性 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 配置檔案中來與所有應用程式共享配置。例如,如果您新增具有以下鍵的秘密,所有使用配置伺服器的應用程式都將可使用屬性 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 層次結構中來與所有應用程式共享配置。
例如,如果您新增具有以下名稱的引數,所有使用配置伺服器的應用程式都將可使用屬性 foo.bar 和 fred.baz:
/config/application/foo.bar
/config/application-default/fred.baz
JDBC 後端
Spring Cloud Config Server 支援 JDBC(關係資料庫)作為配置屬性的後端。您可以透過將 spring-boot-starter-data-jdbc 新增到類路徑並使用 jdbc 配置檔案,或者透過新增型別為 JdbcEnvironmentRepository 的 bean 來啟用此功能。如果您在類路徑中包含正確的依賴項(有關詳細資訊,請參閱使用者指南),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"
}
未指定配置檔案時,將使用 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.* 屬性來選擇儲存配置的儲存桶。
spring:
profiles:
active: awss3
cloud:
config:
server:
awss3:
region: us-east-1
bucket: bucket1
還可以指定一個 AWS URL 來使用 spring.cloud.config.server.awss3.endpoint 覆蓋 S3 服務的標準端點。這允許支援 S3 的測試版區域和其他 S3 相容的儲存 API。
憑據使用 預設憑據提供程式鏈 查詢。版本化和加密的儲存桶無需進一步配置即可支援。
配置檔案以 {application}-{profile}.properties、{application}-{profile}.yml 或 {application}-{profile}.json 形式儲存在您的儲存桶中。可以提供可選標籤以指定檔案的目錄路徑。
未指定配置檔案時,將使用 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 |
no |
AWS Parameter Store 客戶端將使用的區域。如果未明確設定,SDK 將嘗試使用 預設區域提供程式鏈 來確定要使用的區域。 |
|
endpoint |
no |
AWS SSM 客戶端入口點的 URL。這可用於為 API 請求指定備用端點。 |
|
origin |
no |
|
新增到屬性源名稱的字首,以顯示其來源。 |
prefix |
no |
|
表示從 AWS Parameter Store 載入的每個屬性在引數層次結構中的 L1 級別的字首。 |
profile-separator |
no |
|
分隔附加配置檔案與上下文名稱的字串。 |
recursive |
no |
|
指示檢索層次結構中所有 AWS 引數的標誌。 |
decrypt-values |
no |
|
指示檢索所有 AWS 引數並解密其值的標誌。 |
max-results |
no |
|
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 客戶端 ID 應具有 credhub.read 範圍。 |
複合環境倉庫
在某些情況下,您可能希望從多個環境倉庫中拉取配置資料。為此,您可以在配置伺服器的應用程式屬性或 YAML 檔案中啟用 composite 配置檔案。例如,如果您想從 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 倉庫中找到的相同屬性的值。
如果您只想從不同型別的倉庫中拉取配置資料,您可以在配置伺服器的應用程式屬性或 YAML 檔案中啟用相應的配置檔案,而不是 composite 配置檔案。例如,如果您想從單個 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
前面的示例使得所有作為配置客戶端的應用程式都讀取 foo=bar,而不管它們自己的配置如何。
| 配置系統無法強制應用程式以任何特定方式使用配置資料。因此,覆蓋是不可強制執行的。但是,它們確實為 Spring Cloud Config 客戶端提供了有用的預設行為。 |
通常,帶有 ${} 的 Spring 環境佔位符可以透過使用反斜槓 (\) 轉義 $ 或 { 來轉義(並在客戶端解析)。例如,\${app.foo:bar} 解析為 bar,除非應用程式提供了自己的 app.foo。 |
| 在 YAML 中,您不需要轉義反斜槓本身。但是,在屬性檔案中,當您在伺服器上配置覆蓋時,確實需要轉義反斜槓。 |
您可以透過在遠端倉庫中設定 spring.cloud.config.overrideNone=true 標誌(預設值為 false),將客戶端中所有覆蓋的優先順序更改為更像預設值,允許應用程式在環境變數或系統屬性中提供自己的值。
使用 Bootstrap 覆蓋屬性
如果啟用配置優先啟動,您可以透過在客戶端應用程式配置中放置兩個屬性(這些屬性位於配置伺服器使用的外部環境倉庫(例如 Git、Vault、SVN 等)中)來讓客戶端設定覆蓋來自配置伺服器的配置。
spring.cloud.config.allowOverride=true
spring.cloud.config.overrideNone=true
如果啟用了 Bootstrap 並且這兩個屬性都設定為 true,您將能夠從客戶端應用程式配置中覆蓋來自配置伺服器的配置。
使用佔位符覆蓋屬性
一種更簡潔的覆蓋屬性方式,無需啟用配置優先引導,是在來自配置伺服器的配置中使用屬性佔位符。
例如,如果來自配置伺服器的配置包含以下屬性:
hello=${app.hello:Hello From Config Server!}
您可以透過在本地應用程式配置中設定 app.hello 來覆蓋來自配置伺服器的 hello 值:
app.hello=Hello From Application!
使用配置檔案覆蓋屬性
覆蓋來自配置伺服器屬性的最後一種方法是在客戶端應用程式內部的特定於配置檔案的配置檔案中指定它們。
例如,如果您的配置伺服器有以下配置:
hello="Hello From Config Server!"
您可以透過在特定於配置檔案的配置檔案中設定 hello,然後啟用該配置檔案來覆蓋客戶端應用程式中的 hello 值。
hello="Hello From Application!"
在上面的例子中,您必須啟用 overrides 配置檔案。
健康指示器
Config Server 配備了一個健康指示器,用於檢查配置的 EnvironmentRepository 是否正常工作。預設情況下,它會向 EnvironmentRepository 請求一個名為 app 的應用程式、default 配置檔案以及 EnvironmentRepository 實現提供的預設標籤。
您可以配置健康指示器,以檢查更多應用程式以及自定義配置檔案和自定義標籤,如以下示例所示:
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 token),因為 Spring Security 和 Spring Boot 支援許多安全安排。
要使用預設的 Spring Boot 配置的 HTTP 基本安全,請在類路徑中包含 Spring Security(例如,透過 spring-boot-starter-security)。預設使用者名稱是 user,密碼是隨機生成的。隨機密碼在實踐中沒有用,因此我們建議您配置密碼(透過設定 spring.security.user.password)並對其進行加密(請參閱下文了解操作說明)。
Actuator 和安全性
某些平臺會配置健康檢查或類似的東西,並指向 /actuator/health 或其他 Actuator 端點。如果 Actuator 不是配置伺服器的依賴項,則對 /actuator/** 的請求將匹配配置伺服器 API /{application}/{label},可能洩露安全資訊。在這種情況下,請記住新增 spring-boot-starter-actuator 依賴項,並配置使用者,使呼叫 /actuator/** 的使用者無權訪問 /{application}/{label} 處的配置伺服器 API。 |
加密和解密
| 要使用加密和解密功能,您需要在 JVM 中安裝完整強度的 JCE(預設不包含)。您可以從 Oracle 下載“Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files”,並按照安裝說明進行操作(基本上,您需要將 JRE lib/security 目錄中的兩個策略檔案替換為您下載的檔案)。 |
如果遠端屬性源包含加密內容(以 {cipher} 開頭的值),則在透過 HTTP 傳送給客戶端之前對其進行解密。此設定的主要優點是,屬性值在“靜止”時(例如,在 git 倉庫中)不需要是明文。如果值無法解密,則會從屬性源中刪除該值,並新增一個具有相同鍵但字首為 invalid 且值為“不適用”(通常為 <n/a>)的附加屬性。這主要是為了防止密文被用作密碼並意外洩露。
如果您為配置客戶端應用程式設定了遠端配置倉庫,它可能包含一個類似於以下的 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 透過 POST 請求到 /encrypt 端點來加密值,如以下示例所示:
$ curl localhost:8888/encrypt -s -d mysecret 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
如果您正在使用 curl 進行測試,請使用 --data-urlencode(而不是 -d),並在要加密的值前面加上 =(curl 需要這樣做),或者設定明確的 Content-Type: text/plain 以確保 curl 在存在特殊字元(特別是“+”很麻煩)時正確編碼資料。 |
請確保不要在加密值中包含任何 curl 命令統計資訊,這就是為什麼示例中使用 -s 選項來停用它們的原因。將值輸出到檔案有助於避免此問題。 |
逆操作也可以透過 /decrypt 進行(前提是伺服器配置了對稱金鑰或完整的金鑰對),如以下示例所示:
$ curl localhost:8888/decrypt -s -d 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda mysecret
獲取加密值,並在將其放入 YAML 或屬性檔案之前,以及在將其提交併推送到遠端(可能不安全)儲存之前,新增 {cipher} 字首。
/encrypt 和 /decrypt 端點都接受 /*/{application}/{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+...
--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 用於解析檔名。因此,如果您想要一個特定於配置檔案的檔案,/*/development/*/logback.xml 可以透過名為 logback-development.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 參考指南。此外,在使用 Spring Cloud AWS 和 Spring Boot 時,包含 自動配置依賴項 會很有用。然後,您需要配置 Spring Cloud AWS,如 Spring Cloud AWS 參考指南 中所述。
解密純文字
預設情況下,純文字檔案中的加密值不會被解密。為了啟用純文字檔案的解密,請在 bootstrap.[yml|properties] 中設定 spring.cloud.config.server.encrypt.enabled=true 和 spring.cloud.config.server.encrypt.plainTextEncrypt=true。
| 解密純文字檔案僅支援 YAML、JSON 和屬性副檔名。 |
如果啟用此功能並請求不受支援的副檔名,則檔案中的任何加密值都不會被解密。
嵌入 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
如果您使用引導標誌,則 Config Server 需要在其 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)。
推送通知和 Spring Cloud Bus
許多原始碼倉庫提供商(如 Github、Gitlab、Gitea、Gitee、Gogs 或 Bitbucket)透過 Webhook 通知您倉庫中的更改。您可以透過提供商的使用者介面將 Webhook 配置為 URL 和一組您感興趣的事件。例如,Github 使用 POST 請求到 Webhook,其中包含一個包含提交列表的 JSON 主體和一個設定為 push 的標頭(X-Github-Event)。如果您新增對 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} 模式匹配的應用程式(可以包含萬用字元)廣播。
RefreshRemoteApplicationEvent 僅當 spring-cloud-bus 在 Config Server 和客戶端應用程式中都被啟用時才傳輸。 |
| 預設配置還檢測本地 git 倉庫中的檔案系統更改。在這種情況下,不使用 Webhook。但是,一旦您編輯配置檔案,就會廣播重新整理。 |
AOT 和原生映象支援
自 4.0.0 起,Spring Cloud Config Server 支援 Spring AOT 轉換。然而,目前不支援 GraalVM 原生映象。實現原生映象支援受到 graal#5134 的阻礙,並且可能需要完成 https://github.com/graalvm/taming-build-time-initialization 上的工作才能修復。
Spring Cloud Config 客戶端
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。匯入屬性中的位置優先於 uri 屬性。
Spring Boot 配置資料透過兩步過程解析配置。首先,它使用 default 配置檔案載入所有配置。這允許 Spring Boot 收集可能啟用任何附加配置檔案的所有配置。在收集所有已啟用的配置檔案後,它將載入活動配置檔案的任何附加配置。因此,您可能會看到對 Spring Cloud Config Server 發出多個請求以獲取配置。這是正常的,並且是 Spring Boot 在使用 spring.config.import 時載入配置的副作用。在 Spring Cloud Config 的早期版本中,只發出一個請求,但這意味著您無法從 Config Server 的配置中啟用配置檔案。現在,使用“default”配置檔案發出的額外請求使這成為可能。
透過spring.config.import的Spring Boot配置資料匯入方法不需要bootstrap檔案(properties或yaml)。 |
配置優先引導
要使用舊版引導方式連線到 Config Server,必須透過屬性或 spring-cloud-starter-bootstrap 啟動器啟用引導。該屬性是 spring.cloud.bootstrap.enabled=true。它必須設定為系統屬性或環境變數。一旦啟用了引導,類路徑中帶有 Spring Cloud Config Client 的任何應用程式都將按如下方式連線到 Config Server:當配置客戶端啟動時,它會繫結到 Config Server(透過 spring.cloud.config.uri 引導配置屬性),並使用遠端屬性源初始化 Spring Environment。
這種行為的最終結果是,所有想要使用 Config Server 的客戶端應用程式都需要一個 bootstrap.yml(或一個環境變數),其中在 spring.cloud.config.uri 中設定了伺服器地址(預設為“https://:8888”)。
服務發現優先查詢
除非您使用配置優先引導,否則您需要在配置屬性中有一個帶有 optional: 字首的 spring.config.import 屬性。例如,spring.config.import=optional:configserver:。 |
如果您使用 DiscoveryClient 實現,例如 Spring Cloud Netflix 和 Eureka Service Discovery 或 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)。
服務發現客戶端實現都支援某種元資料對映(例如,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 的服務發現優先引導
如果您使用 Spring Cloud Netflix 中的 Eureka DiscoveryClient,並且還想使用 WebClient 而不是 Jersey 或 RestTemplate,您需要在類路徑中包含 WebClient 並設定 eureka.client.webclient.enabled=true。
Config Client 快速失敗
在某些情況下,如果服務無法連線到 Config Server,您可能希望服務啟動失敗。如果這是期望的行為,請將引導配置屬性 spring.cloud.config.fail-fast=true 設定為使客戶端因異常而停止。
要使用 spring.config.import 獲得類似的功能,只需省略 optional: 字首。 |
Config Client 重試
如果您預計應用程式啟動時配置伺服器可能偶爾不可用,您可以在失敗後使其繼續嘗試。首先,您需要設定 spring.cloud.config.fail-fast=true。然後,您需要在類路徑中新增 spring-retry 和 spring-boot-starter-aop。預設行為是重試六次,初始回退間隔為 1000 毫秒,後續回退的指數乘數為 1.1。您可以透過設定 spring.cloud.config.retry.* 配置屬性來配置這些屬性(和其他屬性)。要使用隨機指數回退策略,請將 spring.cloud.config.retry.useRandomPolicy 設定為 true。
要完全控制重試行為並使用舊版引導,請新增一個 ID 為 configServerRetryInterceptor 的 RetryOperationsInterceptor 型別的 @Bean。Spring Retry 有一個 RetryInterceptorBuilder 支援建立這樣的 Bean。 |
使用 spring.config.import 進行 Config Client 重試
重試適用於 Spring Boot spring.config.import 語句和正常屬性。但是,如果匯入語句位於配置檔案中,例如 application-prod.properties,那麼您需要不同的方式來配置重試。配置需要作為 URL 引數放置在匯入語句上。
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 標籤、分支名稱或提交 ID。標籤也可以作為逗號分隔的列表提供。在這種情況下,列表中的項將逐個嘗試,直到一個成功。當在功能分支上工作時,這種行為可能很有用。例如,您可能希望將配置標籤與您的分支對齊,但使其可選(在這種情況下,使用 spring.cloud.config.label=myfeature,develop)。
為配置伺服器指定多個 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(Internal Server Error)響應或 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 基本安全,目前僅當您將憑據嵌入到 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(例如,透過在引導上下文中獲取並注入它)。
健康指示器
Config Client 提供了一個 Spring Boot Health Indicator,它嘗試從 Config Server 載入配置。可以透過設定 health.config.enabled=false 來停用健康指示器。出於效能原因,響應也會被快取。預設的快取存活時間是 5 分鐘。要更改該值,請設定 health.config.time-to-live 屬性(以毫秒為單位)。
提供自定義 RestTemplate
在某些情況下,您可能需要自定義從客戶端向配置伺服器發出的請求。通常,這涉及傳遞特殊的 Authorization 標頭以對伺服器的請求進行身份驗證。
使用配置資料提供自定義 RestTemplate
在使用配置資料時提供自定義 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
使用引導提供自定義 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 和原生映象支援
自 4.0.0 起,Spring Cloud Config Client 支援 Spring AOT 轉換和 GraalVM 原生映象。
AOT 和原生映象支援不適用於配置優先引導(使用 spring.config.use-legacy-processing=true)。 |
原生映象不支援重新整理範圍。如果你將把你的配置客戶端應用程式作為原生映象執行,請確保將 spring.cloud.refresh.enabled 屬性設定為 false。 |
| 在構建包含 Spring Cloud Config Client 的專案時,您必須確保它連線到的配置資料來源(例如,Spring Cloud Config Server、Consul、Zookeeper、Vault 等)可用。例如,如果您從 Spring Cloud Config Server 檢索配置資料,請確保其例項正在執行並在 Config Client 設定中指示的埠可用。這是必要的,因為應用程式上下文是在構建時最佳化的,並且需要解析目標環境。 |
| 由於在 AOT 和原生模式下,配置正在處理並且上下文在構建時進行最佳化,任何會影響 Bean 建立的屬性(例如在引導上下文中使用的屬性)在構建時和執行時都應設定為相同的值,以避免意外行為。 |
| 由於 Config Client 在從原生映象啟動時連線到正在執行的資料來源(例如 Config Server),因此快速啟動時間將因網路通訊所需的時間而減慢。 |
附錄
可觀察性元資料
可觀察性 - 指標
以下是本專案宣告的所有指標列表。
環境倉庫
圍繞 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。
| 在啟動觀測後新增的鍵值可能會從 *.active 指標中缺失。 |
Micrometer 內部使用 納秒 作為基本單位。但是,每個後端確定實際的基本單位。(即 Prometheus 使用秒) |
封閉類的完全限定名 org.springframework.cloud.config.server.environment.DocumentedConfigObservation。
所有標籤都必須以 spring.cloud.config.environment 字首開頭! |
名稱 |
描述 |
|
正在查詢屬性的應用程式名稱。 |
|
EnvironmentRepository 的實現。 |
|
正在查詢屬性的標籤。 |
|
正在查詢屬性的應用程式名稱。 |
可觀察性 - 跨度
以下是本專案宣告的所有 Span 列表。
環境倉庫跨度
圍繞 EnvironmentRepository 建立的觀察。
跨度名稱 spring.cloud.config.environment.find (由約定類 org.springframework.cloud.config.server.environment.ObservationEnvironmentRepositoryObservationConvention 定義)。
封閉類的完全限定名 org.springframework.cloud.config.server.environment.DocumentedConfigObservation。
所有標籤都必須以 spring.cloud.config.environment 字首開頭! |
名稱 |
描述 |
|
正在查詢屬性的應用程式名稱。 |
|
EnvironmentRepository 的實現。 |
|
正在查詢屬性的標籤。 |
|
正在查詢屬性的應用程式名稱。 |