Consul によるサービス検出
サービスディスカバリは、マイクロサービスベースのアーキテクチャの重要な原則の 1 つです。各クライアントや何らかの形式の規則を手動で構成しようとすることは、非常に困難であり、非常に不安定になる可能性があります。Consul は、HTTP API (英語) および DNS (英語) を介して サービスディスカバリサービスを提供します。Spring Cloud Consul は、サービスの登録と検出に HTTP API を利用します。これは、Spring Cloud 以外のアプリケーションが DNS インターフェースを利用することを妨げるものではありません。Consul エージェントサーバーは、ゴシッププロトコル (英語) 経由で通信し、Raft コンセンサスプロトコル (英語) を使用するクラスター (英語) 内で実行されます。
アクティベート方法
Consul Service Discovery をアクティブにするには、グループ org.springframework.cloud およびアーティファクト ID spring-cloud-starter-consul-discovery のスターターを使用します。現在の Spring Cloud リリーストレインを使用したビルドシステムのセットアップの詳細については、Spring Cloud プロジェクトページを参照してください。
Consul への登録
クライアントが Consul に登録すると、ホストとポート、ID、名前、タグなど、それ自体に関するメタデータが提供されます。HTTP チェック (英語) はデフォルトで作成され、Consul が 10 秒ごとに /actuator/health エンドポイントに到達します。ヘルスチェックが失敗した場合、サービスインスタンスはクリティカルとしてマークされます。
Consul クライアントの例:
@SpringBootApplication
@RestController
public class Application {
@RequestMapping("/")
public String home() {
return "Hello world";
}
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}(つまり、まったく通常の Spring Boot アプリ)。Consul クライアントが localhost:8500 以外の場所にある場合は、クライアントを見つけるための構成が必要です。例:
spring:
cloud:
consul:
host: localhost
port: 8500Spring Cloud Consul 構成を使用し、spring.cloud.bootstrap.enabled=true または spring.config.use-legacy-processing=true を設定しているか、spring-cloud-starter-bootstrap を使用している場合は、上記の値を application.yml ではなく bootstrap.yml に入れる必要があります。 |
Environment から取得されたデフォルトのサービス名、インスタンス ID、ポートは、それぞれ ${spring.application.name}、Spring コンテキスト ID および ${server.port} です。
Consul Discovery Client を無効にするには、spring.cloud.consul.discovery.enabled を false に設定します。spring.cloud.discovery.enabled が false に設定されている場合、Consul Discovery Client も無効になります。
サービス登録を無効にするには、spring.cloud.consul.discovery.register を false に設定します。
管理を別のサービスとして登録する
管理サーバーのポートがアプリケーションのポートとは異なるポートに設定されている場合、management.server.port プロパティを設定することで、管理サービスがアプリケーションサービスとは別のサービスとして登録されます。例:
spring:
application:
name: myApp
management:
server:
port: 4452上記の設定では、次の 2 つのサービスが登録されます。
アプリケーションサービス:
ID: myApp Name: myApp
管理サービス:
ID: myApp-management Name: myApp-management
管理サービスは、アプリケーションサービスから instanceId および serviceName を継承します。例:
spring:
application:
name: myApp
management:
server:
port: 4452
spring:
cloud:
consul:
discovery:
instance-id: custom-service-id
serviceName: myprefix-${spring.application.name}上記の設定では、次の 2 つのサービスが登録されます。
アプリケーションサービス:
ID: custom-service-id Name: myprefix-myApp
管理サービス:
ID: custom-service-id-management Name: myprefix-myApp-management
次のプロパティを使用してさらにカスタマイズできます。
/** Port to register the management service under (defaults to management port) */ spring.cloud.consul.discovery.management-port /** Suffix to use when registering management service (defaults to "management") */ spring.cloud.consul.discovery.management-suffix /** Tags to use when registering management service (defaults to "management") */ spring.cloud.consul.discovery.management-tags
HTTP ヘルスチェック
Consul インスタンスのヘルスチェックは、デフォルトで "/actuator/health" に設定されます。これは、Spring Boot Actuator アプリケーションのヘルスエンドポイントのデフォルトの場所です。デフォルト以外のコンテキストパスまたはサーブレットパス (例: server.servletPath=/foo)、または管理エンドポイントパス (例: management.server.servlet.context-path=/admin) を使用する場合は、Actuator アプリケーションであっても、これを変更する必要があります。
Consul が正常性エンドポイントをチェックするために使用する間隔も構成できます。"10s" と "1m" はそれぞれ 10 秒と 1 分を表します。
この例は上記を示しています (その他のオプションについては、付録ページの spring.cloud.consul.discovery.health-check-* プロパティを参照してください)。
spring:
cloud:
consul:
discovery:
healthCheckPath: ${management.server.servlet.context-path}/actuator/health
healthCheckInterval: 15sspring.cloud.consul.discovery.register-health-check=false を設定すると、HTTP ヘルスチェックを完全に無効にすることができます。
ヘッダーの適用
ヘッダーはヘルスチェックリクエストに適用できます。例: Vault バックエンド [GitHub] (英語) を使用する Spring Cloud Config (英語) サーバーを登録しようとしている場合:
spring:
cloud:
consul:
discovery:
health-check-headers:
X-Config-Token: 6442e58b-d1ea-182e-cfa5-cf9cddef0722HTTP 標準によれば、各ヘッダーには複数の値を含めることができ、その場合は配列を指定できます。
spring:
cloud:
consul:
discovery:
health-check-headers:
X-Config-Token:
- "6442e58b-d1ea-182e-cfa5-cf9cddef0722"
- "Some other value"TTL ヘルスチェック
デフォルトで構成された HTTP チェックの代わりに、Consul TTL チェック (英語) を使用できます。主な違いは、Consul エージェントがアプリケーションにリクエストを送信するのではなく、アプリケーションがハートビートシグナルを Consul エージェントに送信することです。
アプリケーションが ping を送信するために使用する間隔も構成できます。"10s" と "1m" はそれぞれ 10 秒と 1 分を表します。デフォルトは 30 秒です。
この例は上記を示しています (その他のオプションについては、付録ページの spring.cloud.consul.discovery.heartbeat.* プロパティを参照してください)。
spring:
cloud:
consul:
discovery:
heartbeat:
enabled: true
ttl: 10sTTL アプリケーションのステータス
Spring Boot Actuator アプリケーションの場合、ステータスは利用可能な正常性エンドポイントから決定されます。正常性エンドポイントが利用できない場合 (無効になっているか、Spring Boot Actuator アプリケーションではない場合)、アプリケーションは正常であると想定されます。
ヘルスエンドポイントをクエリする場合、デフォルトでルートヘルスグループが使用されます。次のプロパティを設定することで、別のヘルスグループを使用できます。
spring:
cloud:
consul:
discovery:
heartbeat:
actuator-health-group: <your-custom-group-goes-here>次のプロパティを設定することで、ヘルスエンドポイントの使用を完全に無効にすることができます。
spring:
cloud:
consul:
discovery:
heartbeat:
use-actuator-health: falseカスタム TTL アプリケーションのステータス
独自のアプリケーションステータスメカニズムを構成したい場合は、ApplicationStatusProvider インターフェースを実装するだけです。
@Bean
public class MyCustomApplicationStatusProvider implements ApplicationStatusProvider {
public CheckStatus currentStatus() {
return yourMethodToDetermineAppStatusGoesHere();
}
}そしてそれをアプリケーションコンテキストで利用できるようにします。
@Bean
public CustomApplicationStatusProvider customAppStatusProvider() {
return new MyCustomApplicationStatusProvider();
}アクチュエーターの健全性インジケーター
サービスインスタンスが Spring Boot Actuator アプリケーションの場合、次のアクチュエーターヘルスインジケーターが提供される場合があります。
DiscoveryClientHealthIndicator
Consul サービスディスカバリがアクティブな場合、DiscoverClientHealthIndicator (英語) が構成され、アクチュエーターの正常性エンドポイントで使用できるようになります。構成オプションについては、ここを参照してください。
ConsulHealthIndicator
ConsulClient の健全性を検証するインジケーターが構成されています。
デフォルトでは、Consul リーダーノードのステータスとすべての登録済みサービスを取得します。多くのサービスが登録されている デプロイでは、ヘルスチェックのたびにすべてのサービスを取得するとコストがかかる場合があります。サービスの取得をスキップし、リーダーノードのステータスのみを確認するには、spring.cloud.consul.health-indicator.include-services-query=false を設定します。
インジケータを無効にするには、management.health.consul.enabled=false を設定します。
| アプリケーションがブートストラップコンテキストモード (英語) (デフォルト) で実行される場合、このインジケーターはブートストラップコンテキストにロードされ、Actuator ヘルスエンドポイントでは使用できません。 |
メタデータ
Consul はサービスのメタデータをサポートします。Spring Cloud の ServiceInstance には、サービス meta フィールドから設定される Map<String, String> metadata フィールドがあります。meta フィールドに値を設定するには、spring.cloud.consul.discovery.metadata または spring.cloud.consul.discovery.management-metadata プロパティの値を設定します。
spring:
cloud:
consul:
discovery:
metadata:
myfield: myvalue
anotherfield: anothervalue 上記の構成により、メタフィールドに myfield→myvalue および anotherfield→anothervalue が含まれるサービスが作成されます。
生成されたメタデータ
Consul 自動登録では、いくつかのエントリが自動的に生成されます。
| キー | 値 |
|---|---|
' グループ ' | プロパティ |
' 安全な ' | プロパティ |
プロパティ | プロパティ |
Spring Cloud Consul の古いバージョンでは、spring.cloud.consul.discovery.tags プロパティを解析することによって、Spring Cloud Commons から ServiceInstance.getMetadata() メソッドを設定していました。これはサポートされなくなりました。spring.cloud.consul.discovery.metadata マップの使用に移行してください。 |
Consul インスタンス ID を一意にする
デフォルトでは、consul インスタンスは Spring アプリケーションコンテキスト ID と同じ ID で登録されます。デフォルトでは、Spring アプリケーションコンテキスト ID は ${spring.application.name}:comma,separated,profiles:${server.port} です。ほとんどの場合、これにより、1 つのサービスの複数のインスタンスを 1 台のマシン上で実行できるようになります。さらに一意性が必要な場合は、Spring Cloud を使用して、spring.cloud.consul.discovery.instanceId に一意の識別子を指定することでこれをオーバーライドできます。例:
spring:
cloud:
consul:
discovery:
instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}} このメタデータと、ローカルホストにデプロイされた複数のサービスインスタンスを使用すると、インスタンスを一意にするためにランダム値がそこに適用されます。Cloudfoundry では、vcap.application.instance_id は Spring Boot アプリケーションに自動的に設定されるため、ランダムな値は必要ありません。
サービスを調べる
ロードバランサの使用
Spring Cloud は、物理 URL の代わりに論理サービス名 /ID を使用してサービスを検索するためのフェイグ (REST クライアントビルダー) と Spring RestTemplate をサポートしています。Feign と検出対応 RestTemplate は両方とも、クライアント側の負荷分散に Spring Cloud LoadBalancer を利用します。
RestTemplate を使用してサービス STORES にアクセスしたい場合は、次のように宣言するだけです。
@LoadBalanced
@Bean
public RestTemplate loadbalancedRestTemplate() {
return new RestTemplate();
}これを次のように使用します (完全修飾ドメイン名の代わりに、Consul の STORES サービス名 /ID を使用していることに注目してください)。
@Autowired
RestTemplate restTemplate;
public String getFirstProduct() {
return this.restTemplate.getForObject("https://STORES/products/1", String.class);
} 複数のデータセンターに Consul クラスターがあり、別のデータセンターのサービスにアクセスしたい場合は、サービス名 /ID だけでは十分ではありません。その場合、プロパティ spring.cloud.consul.discovery.datacenters.STORES=dc-west を使用します。ここで、STORES はサービス名 /ID、dc-west は STORES サービスが存在するデータセンターです。
| Spring Cloud は Spring Cloud LoadBalancer (英語) のサポートも提供するようになりました。 |
DiscoveryClient の使用
Netflix に固有ではない検出クライアント用の単純な API を提供する org.springframework.cloud.client.discovery.DiscoveryClient を使用することもできます。
@Autowired
private DiscoveryClient discoveryClient;
public String serviceUrl() {
List<ServiceInstance> list = discoveryClient.getInstances("STORES");
if (list != null && list.size() > 0 ) {
return list.get(0).getUri();
}
return null;
}Consul カタログウォッチ
Consul Catalog Watch は、領事がサービスを監視できる (英語) 機能を利用しています。Catalog Watch は、ブロッキング Consul HTTP API 呼び出しを実行して、サービスが変更されたかどうかを判断します。新しいサービスデータがある場合は、ハートビートイベントが公開されます。
Config Watch が呼び出される頻度を変更するには、spring.cloud.consul.config.discovery.catalog-services-watch-delay を変更します。デフォルト値は 1000 (ミリ秒単位) です。遅延は、前の呼び出しが終了してから次の呼び出しが開始されるまでの時間です。
カタログウォッチを無効にするには、spring.cloud.consul.discovery.catalogServicesWatch.enabled=false を設定します。
監視は Spring TaskScheduler を使用して領事への呼び出しをスケジュールします。デフォルトでは、poolSize が 1 の ThreadPoolTaskScheduler です。TaskScheduler を変更するには、ConsulDiscoveryClientConfiguration.CATALOG_WATCH_TASK_SCHEDULER_NAME 定数で名前が付けられた TaskScheduler 型の Bean を作成します。