1. 概要

Spring Cloud Consul プロジェクトは、SpringBootアプリケーションのConsulとの簡単な統合を提供します。

Consul は、マイクロサービスアーキテクチャで最も一般的な課題のいくつかを解決するためのコンポーネントを提供するツールです。

  • サービスディスカバリ–サービスインスタンスのネットワークロケーションを自動的に登録および登録解除します
  • ヘルスチェック–サービスインスタンスが稼働していることを検出します
  • 分散構成–すべてのサービスインスタンスが同じ構成を使用するようにします

この記事では、これらの機能を使用するようにSpring Bootアプリケーションを構成する方法を説明します。

2. 前提条件

まず、Consulとそのすべての機能を簡単に確認することをお勧めします。

この記事では、 localhost:8500で実行されているConsulエージェントを使用します。 Consulをインストールしてエージェントを実行する方法の詳細については、このリンクを参照してください。

まず、spring-cloud-starter-consul-all依存関係をpom.xmlに追加する必要があります。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-all</artifactId>
    <version>3.1.1</version>
</dependency>

3. サービスディスカバリ

最初のSpring Bootアプリケーションを作成し、実行中のConsulエージェントと接続しましょう。

@SpringBootApplication
public class ServiceDiscoveryApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(ServiceDiscoveryApplication.class)
          .web(true).run(args);
    }
}

デフォルトでは、Spring Bootはlocalhost:8500でConsulエージェントに接続しようとします。他の設定を使用するには、application.ymlファイルを更新する必要があります。

spring:
  cloud:
    consul:
      host: localhost
      port: 8500

次に、ブラウザで領事館のエージェントのサイト http:// localhost:8500 にアクセスすると、アプリケーションが領事館に“${springの識別子で正しく登録されていることがわかります。 .application.name}:$ {コンマで区切られたプロファイル}:$ {server.port}”

この識別子をカスタマイズするには、プロパティspring.cloud.discovery.instanceIdを別の式で更新する必要があります。

spring:
  application:
    name: myApp
  cloud:
    consul:
      discovery:
        instanceId: ${spring.application.name}:${random.value}

アプリケーションを再度実行すると、識別子「MyApp」とランダムな値を使用して登録されたことがわかります。 これは、ローカルマシンでアプリケーションの複数のインスタンスを実行するために必要です。

最後に、 Service Discoveryを無効にするには、プロパティspring.cloud.consul.discovery.enabledをfalseに設定する必要があります。

3.1. サービスの検索

すでにConsulにアプリケーションが登録されていますが、クライアントはどのようにしてサービスエンドポイントを見つけることができますか? 領事から実行中の利用可能なサービスを取得するには、ディスカバリークライアントサービスが必要です。

Springは、この用のDiscoveryClient APIを提供します。これは、@EnableDiscoveryClientアノテーションで有効にできます。

@SpringBootApplication
@EnableDiscoveryClient
public class DiscoveryClientApplication {
    // ...
}

次に、 DiscoveryClient Beanをコントローラーに挿入し、インスタンスにアクセスできます。

@RestController
public class DiscoveryClientController {
 
    @Autowired
    private DiscoveryClient discoveryClient;

    public Optional<URI> serviceUrl() {
        return discoveryClient.getInstances("myApp")
          .stream()
          .findFirst() 
          .map(si -> si.getUri());
    }
}

最後に、アプリケーションエンドポイントを定義します。

@GetMapping("/discoveryClient")
public String discoveryPing() throws RestClientException, 
  ServiceUnavailableException {
    URI service = serviceUrl()
      .map(s -> s.resolve("/ping"))
      .orElseThrow(ServiceUnavailableException::new);
    return restTemplate.getForEntity(service, String.class)
      .getBody();
}

@GetMapping("/ping")
public String ping() {
    return "pong";
}

「myApp/ping」パスは、サービスエンドポイントを持つSpringアプリケーション名です。 領事は、「myApp」という名前の利用可能なすべてのアプリケーションを提供します。

4. ヘルスチェック

領事は、サービスエンドポイントの状態を定期的にチェックします。

デフォルトでは、 Springは、アプリが稼働している場合に200OKを返すようにヘルスエンドポイントを実装します。 エンドポイントをカスタマイズする場合は、 application.yml:を更新する必要があります

spring:
  cloud:
    consul:
      discovery:
        healthCheckPath: /my-health-check
        healthCheckInterval: 20s

その結果、領事は20秒ごとに「/my-health-check」エンドポイントをポーリングします。

FORBIDDENステータスを返すカスタムヘルスチェックサービスを定義しましょう。

@GetMapping("/my-health-check")
public ResponseEntity<String> myCustomCheck() {
    String message = "Testing my healh check function";
    return new ResponseEntity<>(message, HttpStatus.FORBIDDEN);
}

領事代理店のサイトにアクセスすると、アプリケーションが失敗していることがわかります。 これを修正するには、「/my-health-check」サービスがHTTP200OKステータスコードを返す必要があります。

5. 分散構成

この機能を使用すると、すべてのサービス間で構成を同期できます。 領事は、構成の変更を監視してから、すべてのサービスの更新をトリガーします。

まず、spring-cloud-starter-consul-config依存関係をpom.xmlに追加する必要があります。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-config</artifactId>
    <version>3.1.1</version>
</dependency>

また、ConsulとSpringのアプリケーション名の設定をapplication.ymlファイルからSpringが最初にロードするbootstrap.ymlファイルに移動する必要があります。

次に、Spring CloudConsulConfigを有効にする必要があります。

spring:
  application:
    name: myApp
  cloud:
    consul:
      host: localhost
      port: 8500
      config:
        enabled: true

Spring Cloud Consul Configは、“ / config / myApp”でConsulのプロパティを検索します。 したがって、“ my.prop” というプロパティがある場合は、領事エージェントサイトでこのプロパティを作成する必要があります。

プロパティを作成するには、「KEY / VALUE」セクションに移動し、「CreateKey」[に「/ config / myApp / my/prop」と入力します。 X143X]フォームと「HelloWorld」を値として。 最後に、「作成」ボタンをクリックします。

Springプロファイルを使用している場合は、Springアプリケーション名の横にプロファイルを追加する必要があることに注意してください。 たとえば、 dev プロファイルを使用している場合、Consulの最終パスは“ / config / myApp、dev”になります。

次に、注入されたプロパティを持つコントローラーがどのように見えるかを見てみましょう。

@RestController
public class DistributedPropertiesController {

    @Value("${my.prop}")
    String value;

    @Autowired
    private MyProperties properties;

    @GetMapping("/getConfigFromValue")
    public String getConfigFromValue() {
        return value;
    }

    @GetMapping("/getConfigFromProperty")
    public String getConfigFromProperty() {
        return properties.getProp();
    }
}

そして、 MyProperties クラス:

@RefreshScope
@Configuration
@ConfigurationProperties("my")
public class MyProperties {
    private String prop;

    // standard getter, setter
}

アプリケーションを実行すると、フィールドvaluepropertiesは、Consulからの同じ“ Hello World”値を持ちます。

5.1. 構成の更新

Spring Bootアプリケーションを再起動せずに構成を更新するのはどうですか?

領事エージェントサイトに戻り、プロパティ“ / config / myApp / my / prop” “ New Hello World” のような別の値で更新すると、フィールド[ X166X] value は変更されず、フィールドpropertyは期待どおりに「NewHelloWorld」に更新されます。

これは、フィールドpropertiesMyPropertiesクラスに@RefreshScopeアノテーションがあるためです。 @RefreshScopeアノテーションが付けられたすべてのBeanは、構成の変更後に更新されます。

実生活では、領事館に直接プロパティを置くべきではありませんが、どこかに永続的に保存する必要があります。 これは、 ConfigServerを使用して実行できます。

6. 結論

この記事では、Spring Bootアプリケーションをセットアップして、サービスディスカバリの目的でConsulと連携し、ヘルスチェックルールをカスタマイズし、分散構成を共有する方法を説明しました。

また、クライアントがこれらの登録済みサービスを呼び出すためのいくつかのアプローチを紹介しました。

いつものように、ソースはGitHubにあります。