/*
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.configurationservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@EnableConfigServer
@SpringBootApplication
public class ConfigurationServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigurationServiceApplication.class, args);
}
}
集中式配置
本指南將引導您完成從 Spring Cloud Config Server 建立和使用配置的過程
您將構建什麼
您將建立一個 配置伺服器 並構建一個客戶端,該客戶端在啟動時使用配置,然後在不重啟客戶端的情況下重新整理配置。
您需要什麼
-
大約 15 分鐘
-
一個喜歡的文字編輯器或 IDE
-
Java 17 或更高版本
-
您還可以將程式碼直接匯入到您的 IDE 中
如何完成本指南
與大多數 Spring 入門指南一樣,您可以從頭開始並完成每個步驟,也可以跳過您已熟悉的基本設定步驟。無論哪種方式,您最終都會得到可工作的程式碼。
要從頭開始,請轉到從 Spring Initializr 開始。
要跳過基礎知識,請執行以下操作
-
下載並解壓本指南的源儲存庫,或使用 Git 克隆它:
git clone https://github.com/spring-guides/gs-centralized-configuration.git -
進入
gs-centralized-configuration/initial -
跳到 建立配置伺服器。
完成後,您可以對照 gs-centralized-configuration/complete 中的程式碼檢查您的結果。
從 Spring Initializr 開始
手動初始化專案
-
導航到 https://start.spring.io。此服務會為您拉取應用程式所需的所有依賴項,併為您完成大部分設定。
-
選擇 Gradle 或 Maven 以及您想要使用的語言。本指南假設您選擇了 Java。
-
單擊依賴項並選擇Config Server(用於服務應用程式)或Config Client、Spring Boot Actuator和Spring Web(用於客戶端應用程式)。
-
單擊生成。
-
下載生成的 ZIP 檔案,這是一個已根據您的選擇配置好的 Web 應用程式存檔。
| 如果您的 IDE 集成了 Spring Initializr,您可以從 IDE 中完成此過程。 |
| 您還可以從 Github fork 該專案並在您的 IDE 或其他編輯器中開啟它。 |
建立配置伺服器
您首先需要一個配置服務作為 Spring 應用程式與(通常)版本控制的配置檔案儲存庫之間的中介。您可以使用 Spring Cloud 的 @EnableConfigServer 來建立一個可以與其他應用程式通訊的配置伺服器。這是一個普通的 Spring Boot 應用程式,只添加了一個註解來啟用配置伺服器。以下清單(來自 configuration-service/src/main/java/com/example/configurationservice/ConfigurationServiceApplication.java)展示了這樣一個應用程式
配置伺服器需要知道要管理哪個儲存庫。這裡有幾種選擇,但從基於 Git 檔案系統的儲存庫開始。您可以同樣輕鬆地將配置伺服器指向 Github 或 GitLab 儲存庫。在檔案系統上,建立一個新目錄並在其中執行 git init。然後將一個名為 a-bootiful-client.properties 的檔案新增到 Git 儲存庫。然後執行 git commit。稍後,您將使用一個 Spring Boot 應用程式連線到配置伺服器,該應用程式的 spring.application.name 屬性將其標識為配置伺服器的 a-bootiful-client。這就是配置伺服器如何知道要向特定客戶端傳送哪組配置。它也傳送 Git 儲存庫中任何名為 application.properties 或 application.yml 的檔案中的所有值。更具體命名的檔案(如 a-bootiful-client.properties)中的屬性鍵會覆蓋 application.properties 或 application.yml 中的屬性鍵。
向新建立的 a-bootiful-client.properties 檔案新增一個簡單的屬性和值 (message = Hello world),然後 git commit 更改。
透過在 configuration-service/src/main/resources/application.properties 中指定 spring.cloud.config.server.git.uri 屬性來指定 Git 儲存庫的路徑。您還必須指定不同的 server.port 值,以避免在同一臺機器上執行此伺服器和另一個 Spring Boot 應用程式時發生埠衝突。以下清單(來自 configuration-service/src/main/resources/application.properties)顯示了這樣一個 application.properties 檔案
server.port=8888
spring.cloud.config.server.git.uri=${HOME}/Desktop/config
此示例使用位於 ${HOME}/Desktop/config 的基於檔案的 git 儲存庫。您可以輕鬆地透過建立一個新目錄並在其中對屬性和 YAML 檔案執行 git commit 來建立一個。以下命令集完成了這項工作
$ cd ~/Desktop/config
$ find .
./.git
...
./application.yml
或者,如果您更改應用程式中的配置檔案以指向遠端 git 儲存庫(如 Github),您也可以使用遠端 git 儲存庫。
使用配置客戶端從配置伺服器讀取配置
現在您已經建立了一個配置伺服器,您需要建立一個新的 Spring Boot 應用程式,該應用程式使用配置伺服器載入其自己的配置,並且按需重新整理其配置以反映配置伺服器的更改,而無需重新啟動 JVM。為此,新增 org.springframework.cloud:spring-cloud-starter-config 依賴項,以連線到配置伺服器。Spring 會將配置檔案視為從 application.properties 或 application.yml 或任何其他 PropertySource 載入的任何屬性檔案。
配置配置客戶端的屬性可以像 Spring Boot 應用程式通常那樣設定。在 configuration-client/src/main/resources/application.properties 中將客戶端的 spring.application.name 指定為 a-bootiful-client,並將配置伺服器的位置 (spring.config.import) 指定出來。以下清單顯示了該檔案
configuration-client/src/main/resources/application.properties
spring.application.name=a-bootiful-client
spring.config.import=optional:configserver:https://:8888/
management.endpoints.web.exposure.include=*
您還希望啟用 /refresh 端點,以演示動態配置更改。上面的清單顯示瞭如何透過 management.endpoints.web.exposure.include 屬性來實現這一點。
客戶端可以透過傳統機制(例如 @ConfigurationProperties 或 @Value("${...}") 或透過 Environment 抽象)訪問配置伺服器中的任何值。現在您需要建立一個 Spring MVC REST 控制器,該控制器返回已解析的 message 屬性的值。請參閱 構建 RESTful Web 服務 指南,瞭解有關使用 Spring MVC 和 Spring Boot 構建 REST 服務的更多資訊。
預設情況下,配置值在客戶端啟動時讀取,之後不再讀取。您可以透過使用 Spring Cloud Config 的 @RefreshScope 註解 MessageRestController,然後觸發一個重新整理事件來強制 bean 重新整理其配置(即從配置伺服器拉取更新的值)。以下清單(來自 configuration-client/src/main/java/com/example/configurationclient/ConfigurationClientApplication.java)顯示瞭如何實現這一點
/*
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.configurationclient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class ConfigurationClientApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigurationClientApplication.class, args);
}
}
@RefreshScope
@RestController
class MessageRestController {
@Value("${message:Hello default}")
private String message;
@RequestMapping("/message")
String getMessage() {
return this.message;
}
}
測試應用程式
您可以透過先啟動配置服務,然後一旦它執行起來,再啟動客戶端來測試端到端的結果。在瀏覽器中訪問客戶端應用程式:https://:8080/message。在那裡,您應該在響應中看到 Hello world。
將 Git 儲存庫中 a-bootiful-client.properties 檔案中的 message 鍵更改為不同的內容(也許是 Hello Spring!?)。您可以透過訪問 https://:8888/a-bootiful-client/default 來確認配置伺服器看到了更改。您需要呼叫 refresh Spring Boot Actuator 端點,以強制客戶端重新整理自身並獲取新值。Spring Boot 的 Actuator 暴露了有關應用程式的操作端點(例如健康檢查和環境資訊)。要使用它,您必須將 org.springframework.boot:spring-boot-starter-actuator 新增到客戶端應用程式的類路徑中。您可以透過向客戶端的 refresh 端點發送一個空的 HTTP POST 來呼叫 refresh Actuator 端點:https://:8080/actuator/refresh。然後,您可以透過訪問 https://:8080/message 端點來確認它是否起作用。
以下命令呼叫 Actuator 的重新整理命令
$ curl -X POST localhost:8080/actuator/refresh -d {} -H "Content-Type: application/json"
我們在客戶端應用程式中設定了 management.endpoints.web.exposure.include=* 以便輕鬆測試(因為從 Spring Boot 2.0 開始,Actuator 端點預設不暴露)。預設情況下,如果您不設定該標誌,您仍然可以透過 JMX 訪問它們。 |
總結
恭喜!您剛剛透過首先建立服務,然後動態更新其配置,使用 Spring 集中管理了所有服務的配置。