Spring Cloud Config 集中構成

このガイドでは、Spring Cloud Config サーバー (英語) の構成を立てて使用するプロセスを説明します。

構築するもの

構成サーバー (英語) をセットアップし、起動時に構成を使用し、クライアントを再起動せずに構成をリフレッシュするクライアントを構築します。

必要なもの

本ガイドの完成までの流れ

ほとんどの Spring 入門ガイドと同様に、最初から始めて各ステップを完了するか、すでに慣れている場合は基本的なセットアップステップをバイパスできます。いずれにしても、最終的に動作するコードになります。

最初から始めるには、Spring Initializr から開始に進みます。

基本スキップするには、次の手順を実行します。

完了したときは、gs-centralized-configuration/complete のコードに対して結果を確認できます。

Spring Initializr から開始

この事前に初期化されたプロジェクト(サービスアプリケーションの場合)またはこの事前に初期化されたプロジェクト(クライアントアプリケーションの場合)を使用し、生成をクリックして ZIP ファイルをダウンロードできます。このプロジェクトは、このチュートリアルの例に合うように構成されています。

プロジェクトを手動で初期化するには:

  1. IDE のメニューまたはブラウザーから Spring Initializr を開きます。アプリケーションに必要なすべての依存関係を取り込み、ほとんどのセットアップを行います。

  2. Gradle または Maven のいずれかと、使用する言語を選択します。このガイドは、Java を選択したことを前提としています。

  3. 依存関係をクリックして、構成サーバー(サービスアプリケーションの場合)または構成クライアントSpring Boot ActuatorSpring Web(クライアントアプリケーションの場合)を選択します。

  4. 生成をクリックします。

  5. 結果の ZIP ファイルをダウンロードします。これは、選択して構成された Web アプリケーションのアーカイブです。

EclipseIntelliJ のような IDE は新規プロジェクト作成ウィザードから Spring Initializr の機能が使用できるため、手動での ZIP ファイルのダウンロードやインポートは不要です。
プロジェクトを Github からフォークして、IDE または他のエディターで開くこともできます。

構成サーバーを立ち上げる

まず、Spring アプリケーションと(通常)バージョン管理された構成ファイルのリポジトリとの間の一種の仲介として機能する構成サービスが必要です。Spring Cloud の @EnableConfigServer を使用して、他のアプリケーションと通信できる構成サーバーを立ち上げることができます。これは、構成サーバーを有効にするために 1 つのアノテーションが追加された通常の Spring Boot アプリケーションです。次のリスト(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);
  }
}

構成サーバーは、管理するリポジトリを認識する必要があります。ここにはいくつかの選択肢がありますが、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 リポジトリへのパスを指定します。また、同じマシンでこのサーバーと別の Spring Boot アプリケーションの両方を実行するときにポートの競合を避けるために、異なる server.port 値を指定する必要があります。次のリスト(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 など)を使用できます。

構成クライアントを使用して構成サーバーから構成を読み取る

構成サーバーを立ち上げたため、構成サーバーを使用して独自の構成をロードし、JVM を再始動せずに構成サーバーへの変更をオンデマンドで反映するように構成をリフレッシュする、新しい Spring Boot アプリケーションを立ち上げる必要があります。これを行うには、org.springframework.cloud:spring-cloud-starter-config 依存関係を追加して、構成サーバーに接続します。Spring は、application.properties または application.yml または他の PropertySource からロードされたプロパティファイルと同様に、構成プロパティファイルを参照します。

構成クライアントを構成するためのプロパティは、Spring Boot アプリケーションの通常の方法でセットアップできます。クライアントの spring.application.name を a-bootiful-client として指定し、構成サーバーの場所(spring.config.import)を configuration-client/src/main/resources/application.properties で指定します。次のリストは、そのファイルを示しています。

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

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

また、動的な構成変更を示すために、/refresh エンドポイントを有効にする必要があります。上記のリストは、management.endpoints.web.exposure.include プロパティを介してこれを行う方法を示しています。

クライアントは、従来のメカニズム (@ConfigurationProperties または @Value("${ …​ }") または Environment 抽象化など) を使用して、構成サーバー内の任意の値にアクセスできます。次に、解決された message プロパティの値を返す Spring MVC REST コントローラーを作成する必要があります。Spring MVC および Spring Boot を使用した REST サービスの構築の詳細については、REST API の作成ガイドを参照してください。

デフォルトでは、構成値はクライアントの起動時に読み取られ、再度ではありません。MessageRestController に Spring Cloud Config @RefreshScope のアノテーションを付けてからリフレッシュイベントをトリガーすることにより、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;
  }
}

アプリケーションをテストする

エンドツーエンドの結果をテストするには、最初に構成サービスを開始してから、実行後にクライアントを開始します。http://localhost:8080/message のブラウザーでクライアントアプリにアクセスします。そこで、レスポンスに Hello world が表示されるはずです。

Git リポジトリの a-bootiful-client.properties ファイルの message キーを別の何かに変更します(おそらく Hello Spring! ですか? )。http://localhost:8888/a-bootiful-client/default にアクセスすると、構成サーバーが変更を認識していることを確認できます。クライアントを強制的にリフレッシュして新しい値を描画するには、refresh Spring Boot Actuator エンドポイントを呼び出す必要があります。Spring Boot のアクチュエーターは、アプリケーションに関する運用エンドポイント(ヘルスチェックや環境情報など)を公開します。これを使用するには、org.springframework.boot:spring-boot-starter-actuator をクライアントアプリケーションのクラスパスに追加する必要があります。空の HTTP POST をクライアントの refresh エンドポイント http://localhost:8080/actuator/refresh に送信することにより、refresh アクチュエーターエンドポイントを呼び出すことができます。次に、http://localhost:8080/message エンドポイントにアクセスして、機能したことを確認できます。

次のコマンドは、アクチュエーターのリフレッシュコマンドを呼び出します。

$ curl -X POST localhost:8080/actuator/refresh -d {} -H "Content-Type: application/json"
クライアントアプリケーションで management.endpoints.web.exposure.include=* を設定して、これを簡単にテストできるようにしました(Spring Boot 2.0 であるため、アクチュエーターのエンドポイントはデフォルトで公開されていません)。デフォルトでは、フラグを設定しなくても、JMX を介してそれらにアクセスできます。

要約

おめでとう! Spring を使用して、最初にサービスを立ち上げ、次にその構成を動的に更新することにより、すべてのサービスの構成を一元化しました。

関連事項

次のガイドも役立つかもしれません:

新しいガイドを作成したり、既存のガイドに貢献したいですか? 投稿ガイドラインを参照してください [GitHub] (英語)

すべてのガイドは、コード用の ASLv2 ライセンス、およびドキュメント用の Attribution、NoDerivatives creative commons ライセンス (英語) でリリースされています。

コードを入手する