集中式配置

本指南將引導您完成啟動和使用來自 Spring Cloud Config Server 的配置的過程

您將建構的內容

您將設定一個 Config Server,並建構一個用戶端,該用戶端在啟動時使用配置,然後重新整理配置,而無需重新啟動用戶端。

您需要的東西

如何完成本指南

如同大多數 Spring 入門指南,您可以從頭開始並完成每個步驟,或者您可以跳過您已熟悉的基礎設定步驟。無論哪種方式,您最終都會得到可運作的程式碼。

若要從頭開始,請繼續前往 從 Spring Initializr 開始

若要跳過基礎知識,請執行以下操作

當您完成時,您可以對照 gs-centralized-configuration/complete 中的程式碼檢查您的結果。

從 Spring Initializr 開始

您可以使用這個 預先初始化的專案 (適用於服務應用程式) 或這個 預先初始化的專案 (適用於用戶端應用程式),然後按一下 Generate 以下載 ZIP 檔案。此專案已配置為符合本教學課程中的範例。

若要手動初始化專案

  1. 導覽至 https://start.spring.io。此服務會提取應用程式所需的所有相依性,並為您完成大部分設定。

  2. 選擇 Gradle 或 Maven 以及您想要使用的語言。本指南假設您選擇 Java。

  3. 按一下 Dependencies,然後選取 Config Server (適用於服務應用程式) 或 Config ClientSpring Boot ActuatorSpring Web (適用於用戶端應用程式)。

  4. 按一下 Generate

  5. 下載產生的 ZIP 檔案,這是一個使用您的選擇配置的 Web 應用程式的封存檔。

如果您的 IDE 具有 Spring Initializr 整合,您可以從您的 IDE 完成此程序。
您也可以從 Github 分支專案,並在您的 IDE 或其他編輯器中開啟它。

啟動 Config Server

您首先需要一個 Config Service 作為 Spring 應用程式和 (通常) 版本控制的組態檔儲存庫之間的中介。您可以使用 Spring Cloud 的 @EnableConfigServer 來啟動可以與其他應用程式通訊的 config server。這是一個常規的 Spring Boot 應用程式,其中新增了一個註解以啟用 config server。以下清單 (來自 configuration-service/src/main/java/com/example/configurationservice/ConfigurationServiceApplication.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.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);
  }
}

Config Server 需要知道要管理哪個儲存庫。這裡有多種選擇,但從基於 Git 的檔案系統儲存庫開始。您可以同樣輕鬆地將 Config Server 指向 Github 或 GitLab 儲存庫。在檔案系統上,建立一個新目錄並在其中執行 git init。然後在 Git 儲存庫中新增一個名為 a-bootiful-client.properties 的檔案。然後在其中執行 git commit。稍後,您將使用 Spring Boot 應用程式連線到 Config Server,其 spring.application.name 屬性將其識別為 a-bootiful-client 給 Config Server。這就是 Config Server 知道要將哪組配置傳送給特定用戶端的方式。它會傳送 Git 儲存庫中任何名為 application.propertiesapplication.yml 的檔案中的所有值。更具體命名的檔案 (例如 a-bootiful-client.properties) 中的屬性鍵會覆寫 application.propertiesapplication.yml 中的屬性鍵。

將一個簡單的屬性和值 (message = Hello world) 新增到新建立的 a-bootiful-client.properties 檔案,然後 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

此範例使用基於檔案的 git 儲存庫,位於 ${HOME}/Desktop/config。您可以透過建立一個新目錄並在其中的屬性和 YAML 檔案上執行 git commit 來輕鬆建立一個。以下命令集執行此工作

$ cd ~/Desktop/config
$ find .
./.git
...
./application.yml

或者,如果您變更應用程式中的組態檔以指向它,則可以使用遠端 git 儲存庫 (例如 Github)。

透過使用 Config Client 從 Config Server 讀取配置

現在您已經啟動了 Config Server,您需要啟動一個新的 Spring Boot 應用程式,該應用程式使用 Config Server 來載入其自身的配置,並重新整理其配置以反映對 Config Server 的隨需變更,而無需重新啟動 JVM。若要執行此操作,請新增 org.springframework.cloud:spring-cloud-starter-config 相依性,以連線到 Config Server。Spring 會看到組態屬性檔,就像它會看到從 application.propertiesapplication.yml 或任何其他 PropertySource 載入的任何屬性檔一樣。

Config Client 的配置屬性可以使用 Spring Boot 應用程式的常用方式設定。在 configuration-client/src/main/resources/application.properties 中,將用戶端的 spring.application.name 指定為 a-bootiful-client,並指定 Config Server 的位置 (spring.config.import)。以下清單顯示了該檔案

configuration-client/src/main/resources/application.properties

spring.application.name=a-bootiful-client
spring.config.import=optional:configserver:https://127.0.0.1:8888/
management.endpoints.web.exposure.include=*

您也想要啟用 /refresh 端點,以示範動態配置變更。上面的清單顯示了如何透過 management.endpoints.web.exposure.include 屬性來執行此操作。

用戶端可以使用傳統機制 (例如 @ConfigurationProperties@Value("${…​}") 或透過 Environment 抽象) 存取 Config Server 中的任何值。現在您需要建立一個 Spring MVC REST 控制器,該控制器傳回已解析的 message 屬性的值。請參閱 建構 RESTful Web Service 指南,以深入瞭解如何使用 Spring MVC 和 Spring Boot 建構 REST 服務。

預設情況下,配置值在用戶端啟動時讀取,之後不再讀取。您可以透過使用 Spring Cloud Config @RefreshScope 註解 MessageRestController,然後觸發重新整理事件,來強制 bean 重新整理其配置 (也就是說,從 Config Server 提取更新的值)。以下清單 (來自 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;
  }
}

測試應用程式

您可以先啟動 Config Service,然後在其執行後啟動用戶端,來測試端對端結果。在瀏覽器中瀏覽用戶端應用程式,網址為 https://127.0.0.1:8080/message。在那裡,您應該在回應中看到 Hello world

將 Git 儲存庫中 a-bootiful-client.properties 檔案中的 message 鍵變更為其他內容 (也許是 Hello Spring!?)。您可以透過瀏覽 https://127.0.0.1:8888/a-bootiful-client/default 來確認 Config Server 是否看到變更。您需要叫用 refresh Spring Boot Actuator 端點,才能強制用戶端重新整理自身並提取新值。Spring Boot 的 Actuator 公開關於應用程式的操作端點 (例如健康檢查和環境資訊)。若要使用它,您必須將 org.springframework.boot:spring-boot-starter-actuator 新增至用戶端應用程式的類別路徑。您可以透過傳送一個空的 HTTP POST 到用戶端的 refresh 端點來叫用 refresh Actuator 端點:https://127.0.0.1:8080/actuator/refresh。然後您可以透過瀏覽 https://127.0.0.1:8080/message 端點來確認它是否運作。

以下命令叫用 Actuator 的 refresh 命令

$ 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 為您的所有服務集中配置,方法是先啟動一個服務,然後動態更新其配置。

另請參閱

以下指南也可能有所幫助

想要撰寫新的指南或貢獻現有的指南嗎?請查看我們的 貢獻指南

所有指南均以 ASLv2 授權發佈程式碼,並以 姓名標示-禁止改作創用 CC 授權條款 3.0 發佈寫作內容。

取得程式碼