このバージョンはまだ開発中であり、まだ安定しているとは見なされていません。最新の安定バージョンについては、Spring Cloud Commons 5.0.3 を使用してください! |
Spring Cloud LoadBalancer
Spring Cloud は、独自のクライアント側ロードバランサーの抽象化と実装を提供します。負荷分散メカニズムについては、ReactiveLoadBalancer インターフェースが追加され、ラウンドロビンベースおよびランダム実装が提供されています。リアクティブから選択するインスタンスを取得するには、ServiceInstanceListSupplier が使用されます。現在、クラスパスで使用可能なディスカバリクライアントを使用してサービスディスカバリから利用可能なインスタンスを取得する、サービスディスカバリベースの ServiceInstanceListSupplier 実装をサポートしています。
spring.cloud.loadbalancer.enabled の値を false に設定することで、Spring Cloud LoadBalancer を無効にすることができます。 |
LoadBalancer コンテキストの積極的なロード
Spring Cloud LoadBalancer は、サービス ID ごとに個別の Spring 子コンテキストを作成します。デフォルトでは、サービス ID に対する最初のリクエストが負荷分散されるたびに、これらのコンテキストは遅延初期化されます。
これらのコンテキストを積極的にロードすることを選択できます。そのためには、spring.cloud.loadbalancer.eager-load.clients プロパティを使用して、積極的にロードするサービス ID を指定します。例:
spring.cloud-loadbalancer.eager-load.clients[0]=my-first-client
spring.cloud-loadbalancer.eager-load.clients[1]=my-second-client負荷分散アルゴリズムの切り替え
デフォルトで使用される ReactiveLoadBalancer 実装は RoundRobinLoadBalancer です。選択したサービスまたはすべてのサービスを別の実装に切り替えるには、カスタム LoadBalancer 構成メカニズムを使用できます。
例: 次の設定を @LoadBalancerClient アノテーション経由で渡して、RandomLoadBalancer の使用に切り替えることができます。
public class CustomLoadBalancerConfiguration {
@Bean
ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RandomLoadBalancer(loadBalancerClientFactory
.getLazyProvider(name, ServiceInstanceListSupplier.class),
name);
}
}@LoadBalancerClient または @LoadBalancerClients 構成引数として渡すクラスは、@Configuration のアノテーションが付けられていないか、コンポーネントのスキャン範囲外である必要があります。 |
Spring Cloud LoadBalancer の統合
Spring Cloud LoadBalancer を簡単に使用できるように、ReactorLoadBalancerExchangeFilterFunction ( WebClient で使用可能) および BlockingLoadBalancerClient (RestTemplate および RestClient で使用可能) を提供します。詳細と使用例については、次のセクションで説明します。
Spring Cloud LoadBalancer キャッシング
インスタンスを選択する必要があるたびに DiscoveryClient 経由でインスタンスを取得する基本的な ServiceInstanceListSupplier 実装とは別に、2 つのキャッシュ実装が提供されています。
Caffeine [GitHub] (英語) - バックアップされた LoadBalancer キャッシュ実装
クラスパスに com.github.ben-manes.caffeine:caffeine がある場合は、Caffeine ベースの実装が使用されます。設定方法については、"LoadBalancerCacheConfiguration" セクションを参照してください。
Caffeine を使用している場合は、spring.cloud.loadbalancer.cache.caffeine.spec プロパティに独自の Caffeine 仕様 (英語) を渡すことで、LoadBalancer のデフォルトの Caffeine キャッシュ設定をオーバーライドすることもできます。
独自の Caffeine 仕様を渡すと、ttl や capacity などの一般的な LoadBalancer キャッシュ構成フィールドを含む他の LoadBalancerCache 設定がオーバーライドされます。 |
デフォルトの LoadBalancer キャッシュ実装
クラスパスに Caffeine がない場合は、spring-cloud-starter-loadbalancer に自動的に付属する DefaultLoadBalancerCache が使用されます。設定方法については、"LoadBalancerCacheConfiguration" セクションを参照してください。
デフォルトのキャッシュの代わりに Caffeine を使用するには、クラスパスに com.github.ben-manes.caffeine:caffeine 依存関係を追加します。 |
LoadBalancer キャッシュ構成
spring.cloud.loadbalancer.cache.ttl プロパティの値として Spring Boot String から Duration へのコンバーターの構文に準拠した String を渡すことで、ttl 値(書き込み後、エントリが期限切れとなるまでの時間)を Duration として独自に設定できます。また、spring.cloud.loadbalancer.cache.capacity プロパティの値を設定することで、LoadBalancer キャッシュの初期容量を独自に設定することもできます。
デフォルトの設定には、35 秒に設定された ttl が含まれており、デフォルトの initialCapacity は 256 です。
spring.cloud.loadbalancer.cache.enabled の値を false に設定することで、loadBalancer キャッシュを完全に無効にすることもできます。
基本的なキャッシュされていない実装はプロトタイピングやテストには役立ちますが、キャッシュされたバージョンよりも効率がはるかに低いため、運用環境では常にキャッシュされたバージョンを使用することをお勧めします。DiscoveryClient 実装 ( EurekaDiscoveryClient など) によってキャッシュがすでに行われている場合は、二重キャッシュを防ぐためにロードバランサーのキャッシュを無効にする必要があります。 |
独自の構成を作成する場合、CachingServiceInstanceListSupplier を使用する場合は、ネットワーク経由でインスタンスを取得するサプライヤー ( DiscoveryClientServiceInstanceListSupplier など) の直後の階層内で、他のフィルタリングサプライヤーの前に必ず配置してください。 |
加重負荷分散
加重ロードバランシングを有効にするために、WeightedServiceInstanceListSupplier が提供されています。WeightFunction を使用して各インスタンスの重みを計算します。デフォルトでは、メタデータマップから重みを読み取って解析しようとします (キーは weight)。
メタデータマップで重みが指定されていない場合、このインスタンスの重みはデフォルトで 1 になります。
これを構成するには、spring.cloud.loadbalancer.configurations の値を weighted に設定するか、独自の ServiceInstanceListSupplier Bean を指定します。例:
public class CustomLoadBalancerConfiguration {
@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withCaching()
.withWeighted()
.build(context);
}
}WeightFunction を提供することで、重み計算ロジックをカスタマイズすることもできます。 |
このサンプル構成を使用すると、すべてのインスタンスにランダムな重みを持たせることができます。
public class CustomLoadBalancerConfiguration {
@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withCaching()
.withWeighted(instance -> ThreadLocalRandom.current().nextInt(1, 101))
.build(context);
}
}ゾーンベースの負荷分散
ゾーンベースの負荷分散を有効にするために、ZonePreferenceServiceInstanceListSupplier が提供されています。DiscoveryClient -specific zone 構成 (たとえば、eureka.instance.metadata-map.zone) を使用して、クライアントが利用可能なサービスインスタンスをフィルタリングしようとするゾーンを選択します。
spring.cloud.loadbalancer.zone プロパティの値を設定することで、DiscoveryClient -specific ゾーン設定をオーバーライドすることもできます。 |
当面は、LoadBalancer ゾーンを設定するために Eureka Discovery Client のみが装備されています。他の検出クライアントの場合は、spring.cloud.loadbalancer.zone プロパティを設定します。さらに多くの機器が間もなく登場します。 |
取得した ServiceInstance のゾーンを判断するには、そのメタデータマップ内の "zone" キーの値を確認します。 |
ZonePreferenceServiceInstanceListSupplier は、取得したインスタンスをフィルタリングし、同じゾーン内のインスタンスのみを返します。ゾーンが null である場合、または同じゾーン内にインスタンスがない場合は、取得されたすべてのインスタンスが返されます。
ゾーンベースの負荷分散アプローチを使用するには、カスタム構成で ZonePreferenceServiceInstanceListSupplier Bean をインスタンス化する必要があります。
ServiceInstanceListSupplier Bean を操作するためにデリゲートを使用します。DiscoveryClientServiceInstanceListSupplier デリゲートを使用し、それを CachingServiceInstanceListSupplier でラップして LoadBalancer キャッシュメカニズムを利用し、結果の Bean を ZonePreferenceServiceInstanceListSupplier のコンストラクターに渡すことをお勧めします。
このサンプル構成を使用してセットアップできます。
public class CustomLoadBalancerConfiguration {
@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withCaching()
.withZonePreference()
.build(context);
}
}LoadBalancer のインスタンスのヘルスチェック
LoadBalancer に対してスケジュールされた HealthCheck を有効にすることができます。HealthCheckServiceInstanceListSupplier はそのために提供されています。デリゲート ServiceInstanceListSupplier によって提供されたインスタンスがまだ生きているかどうかを定期的に確認し、正常なインスタンスのみを返します (存在しない場合は、取得したすべてのインスタンスを返します)。
このメカニズムは、SimpleDiscoveryClient を使用する場合に特に役立ちます。実際のサービスレジストリによってサポートされているクライアントの場合、外部 ServiceDiscovery にクエリを実行した後、正常なインスタンスがすでに取得されているため、サービスレジストリを使用する必要はありません。 |
| このサプライヤーは、失敗したインスタンスでの呼び出しの再試行を避けるために、サービスあたりのインスタンス数が少ないセットアップにも推奨されます。 |
| サービスディスカバリがサポートするサプライヤーを使用している場合は、インスタンスの健全性状態を Service Registry から直接取得するため、通常、この健全性チェックメカニズムを追加する必要はありません。 |
HealthCheckServiceInstanceListSupplier は、デリゲート flux によって提供される最新のインスタンスに依存しています。インスタンスのリストが変更される可能性がある場合でも、インスタンスをリフレッシュしないデリゲートを使用したいまれなケース (弊社が提供する DiscoveryClientServiceInstanceListSupplier など) では、spring.cloud.loadbalancer.health-check.refetch-instances を true に設定して、インスタンスリストを HealthCheckServiceInstanceListSupplier によってリフレッシュすることができます。また、spring.cloud.loadbalancer.health-check.refetch-instances-interval の値を変更して再取得間隔を調整したり、spring.cloud.loadbalancer.health-check.repeat-health-check を false に設定して追加のヘルスチェックの繰り返しを無効にしたりすることもできます。インスタンスの再取得のたびにヘルスチェックがトリガーされるためです。 |
HealthCheckServiceInstanceListSupplier は、spring.cloud.loadbalancer.health-check という接頭辞が付いているプロパティを使用します。スケジューラーには initialDelay と interval を設定できます。spring.cloud.loadbalancer.health-check.path.default プロパティの値を設定することで、ヘルスチェック URL のデフォルトのパスを設定できます。spring.cloud.loadbalancer.health-check.path.[SERVICE_ID] プロパティの値を設定し、[SERVICE_ID] をサービスの正しい ID に置き換えることにより、特定のサービスに特定の値を設定することもできます。[SERVICE_ID] が指定されていない場合は、デフォルトで /actuator/health が使用されます。[SERVICE_ID] が null に設定されている場合、または値が空の場合、ヘルスチェックは実行されません。spring.cloud.loadbalancer.health-check.port の値を設定することで、ヘルスチェックリクエスト用のカスタムポートを設定することもできます。何も設定されていない場合、リクエストされたサービスをサービスインスタンスで使用できるポート。
デフォルトのパス (/actuator/health) に依存する場合は、そのようなエンドポイントを独自に追加する予定がない限り、必ず spring-boot-starter-actuator をコラボレーターの依存関係に追加してください。 |
デフォルトでは、healthCheckFlux は取得された各生存 ServiceInstance に対して発行します。この動作は、spring.cloud.loadbalancer.health-check.update-results-list の値を false に設定することで変更できます。このプロパティが false に設定されている場合、生存インスタンスのシーケンス全体が最初にリストに収集され、その後発行されます。これにより、プロパティで設定されたヘルスチェック間隔の間に flux が値を発行しないことが保証されます。 |
ヘルスチェックスケジューラのアプローチを使用するには、カスタム構成で HealthCheckServiceInstanceListSupplier Bean をインスタンス化する必要があります。
ServiceInstanceListSupplier Bean を操作するためにデリゲートを使用します。HealthCheckServiceInstanceListSupplier のコンストラクターで DiscoveryClientServiceInstanceListSupplier デリゲートを渡すことをお勧めします。
このサンプル構成を使用してセットアップできます。
public class CustomLoadBalancerConfiguration {
@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withHealthChecks()
.build(context);
}
} 非リアクティブスタックの場合は、withBlockingHealthChecks() を使用してこのサプライヤーを作成します。チェックに使用する独自の WebClient、RestTemplate、または RestClient インスタンスを渡すこともできます。 |
HealthCheckServiceInstanceListSupplier には、Reactor Flux replay() に基づく独自のキャッシュメカニズムがあります。これが使用されている場合は、そのサプライヤーを CachingServiceInstanceListSupplier でラップするのをスキップすることをお勧めします。 |
独自の構成 HealthCheckServiceInstanceListSupplier を作成する場合は、ネットワーク経由でインスタンスを取得するサプライヤー ( DiscoveryClientServiceInstanceListSupplier など) の直後の階層内で、他のフィルタリングサプライヤーの前に必ず配置してください。 |
LoadBalancer の同じインスタンス設定
以前に選択されたインスタンスが使用可能な場合、そのインスタンスが優先されるように LoadBalancer をセットアップできます。
そのためには、SameInstancePreferenceServiceInstanceListSupplier を使用する必要があります。これを構成するには、spring.cloud.loadbalancer.configurations の値を same-instance-preference に設定するか、独自の ServiceInstanceListSupplier Bean を指定します。たとえば、次のようになります。
public class CustomLoadBalancerConfiguration {
@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withSameInstancePreference()
.build(context);
}
} これも Zookeeper StickyRule の代替です。 |
LoadBalancer のリクエストベースのスティッキーセッション
リクエスト Cookie で提供される instanceId を持つインスタンスが優先されるように LoadBalancer をセットアップできます。現在、リクエストが ClientRequestContext または ServerHttpRequestContext を介して LoadBalancer に渡される場合、これはサポートされています。これらは SC LoadBalancer 交換フィルター関数およびフィルターによって使用されます。
そのためには、RequestBasedStickySessionServiceInstanceListSupplier を使用する必要があります。これを構成するには、spring.cloud.loadbalancer.configurations の値を request-based-sticky-session に設定するか、独自の ServiceInstanceListSupplier Bean を指定します。たとえば、次のようになります。
public class CustomLoadBalancerConfiguration {
@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withRequestBasedStickySession()
.build(context);
}
} この機能では、リクエストを転送する前に、選択したサービスインスタンス (元のリクエスト Cookie が使用できない場合は、そのサービスインスタンスと異なる可能性があります) を更新できると便利です。これを行うには、spring.cloud.loadbalancer.sticky-session.add-service-instance-cookie の値を true に設定します。
デフォルトでは、Cookie の名前は sc-lb-instance-id です。spring.cloud.loadbalancer.instance-id-cookie-name プロパティの値を変更することで変更できます。
| この機能は現在、WebClient ベースのロードバランシングでサポートされています。 |
Spring Cloud LoadBalancer ヒント
Spring Cloud LoadBalancer を使用すると、Request オブジェクト内の LoadBalancer に渡され、後で処理できる ReactiveLoadBalancer 実装で使用できる String ヒントを設定できます。
spring.cloud.loadbalancer.hint.default プロパティの値を設定することで、すべてのサービスのデフォルトのヒントを設定できます。spring.cloud.loadbalancer.hint.[SERVICE_ID] プロパティの値を設定し、[SERVICE_ID] をサービスの正しい ID に置き換えることにより、特定のサービスに特定の値を設定することもできます。ユーザーがヒントを設定しない場合は、default が使用されます。
ヒントベースの負荷分散
また、ヒントベースのインスタンス選択のための ServiceInstanceListSupplier 実装である HintBasedServiceInstanceListSupplier も提供します。
HintBasedServiceInstanceListSupplier は、ヒントリクエストヘッダー (デフォルトのヘッダー名は X-SC-LB-Hint ですが、spring.cloud.loadbalancer.hint-header-name プロパティの値を変更することで変更できます) をチェックし、ヒントリクエストヘッダーが見つかった場合は、ヘッダーに渡されたヒント値を使用してフィルターします。サービスインスタンス。
ヒントヘッダーが追加されていない場合、HintBasedServiceInstanceListSupplier はプロパティからのヒント値を使用してサービスインスタンスをフィルターします。
ヘッダーまたはプロパティによってヒントが設定されていない場合は、デリゲートによって提供されたすべてのサービスインスタンスが返されます。
フィルタリング中に、HintBasedServiceInstanceListSupplier は、metadataMap の hint キーに設定された一致する値を持つサービスインスタンスを検索します。一致するインスタンスが見つからない場合は、デリゲートによって提供されたすべてのインスタンスが返されます。
次のサンプル構成を使用してセットアップできます。
public class CustomLoadBalancerConfiguration {
@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withCaching()
.withHints()
.build(context);
}
}負荷分散された HTTP リクエストを変換する
選択した ServiceInstance を使用して、負荷分散された HTTP リクエストを変換できます。
RestTemplate および RestClient の場合、次のように LoadBalancerRequestTransformer を実装して定義する必要があります。
@Bean
public LoadBalancerRequestTransformer transformer() {
return new LoadBalancerRequestTransformer() {
@Override
public HttpRequest transformRequest(HttpRequest request, ServiceInstance instance) {
return new HttpRequestWrapper(request) {
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.putAll(super.getHeaders());
headers.add("X-InstanceId", instance.getInstanceId());
return headers;
}
};
}
};
}WebClient の場合、次のように LoadBalancerClientRequestTransformer を実装して定義する必要があります。
@Bean
public LoadBalancerClientRequestTransformer transformer() {
return new LoadBalancerClientRequestTransformer() {
@Override
public ClientRequest transformRequest(ClientRequest request, ServiceInstance instance) {
return ClientRequest.from(request)
.header("X-InstanceId", instance.getInstanceId())
.build();
}
};
} 複数のトランスフォーマが定義されている場合、Bean が定義されている順序で適用されます。または、LoadBalancerRequestTransformer.DEFAULT_ORDER または LoadBalancerClientRequestTransformer.DEFAULT_ORDER を使用して順序を指定することもできます。
Spring Cloud LoadBalancer サブセット
SubsetServiceInstanceListSupplier は、決定論的なサブセットアルゴリズム (英語) を実装して、ServiceInstanceListSupplier デリゲート階層内の限られた数のインスタンスを選択します。
これを構成するには、spring.cloud.loadbalancer.configurations の値を subset に設定するか、独自の ServiceInstanceListSupplier Bean を指定します。たとえば、次のようになります。
public class CustomLoadBalancerConfiguration {
@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withCaching()
.withSubset()
.build(context);
}
} デフォルトでは、各サービスインスタンスには一意の instanceId が割り当てられ、多くの場合、異なる instanceId 値により異なるサブセットが選択されます。通常は特に注意する必要はありません。ただし、複数のインスタンスに同じサブセットを選択させる必要がある場合は、spring.cloud.loadbalancer.subset.instance-id (プレースホルダーをサポートする) を使用して設定できます。 |
デフォルトでは、サブセットのサイズは 100 に設定されています。spring.cloud.loadbalancer.subset.size を使用して設定することもできます。 |
API バージョンベースの負荷分散
API バージョンベースの負荷分散を有効にするために、クライアントが Spring、RestClient、WebClient のいずれを使用するかに応じて使用できる BlockingApiVersionServiceInstanceListSupplier と ReactiveApiVersionServiceInstanceListSupplier を提供します。
spring.cloud.loadbalancer.configurations を api-version に設定するか、すべてまたは特定の LoadBalancer serviceIds に対して API バージョン管理が構成された ServiceInstanceListSupplier Bean を提供することで、API バージョン管理を有効にすることができます。
public class CustomLoadBalancerConfiguration {
@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withCaching()
// Use withBlockingApiVersioning() for blocking clients
.withReactiveApiVersioning()
.build(context);
}
}内部的には、Spring Framework のブロッキングおよびリアクティブ API バージョン管理サポートを使用しています。リクエスト要素に基づいてバージョンがどのように解析、比較、照合されるかについては、フレームワークのドキュメントを参照してください。提供される LoadBalancer API バージョン管理戦略がデフォルトの戦略と異なる点の 1 つは、バージョンの検証を行わず、ユーザーが任意のバージョンを指定できるようにすることです。
この機能を使用するには、LoadBalancerProperties.ApiVersion を使用してバージョンを取得するリクエスト要素を指定する必要があります。spring.cloud.load-balancer.clients.<serviceId>.api-version プロパティプレフィックスを使用すると、リクエストで必要なバージョンを渡すために使用する header、queryParameter、pathSegment または mediaTypeParameters を指定できます。また、リクエストでバージョンが渡されなかった場合に使用する defaultVersion と、API バージョンを渡す際に required を使用するかどうかも設定できます。
API バージョン管理機能が有効になり、defaultVersion のリクエスト要素のいずれかを通じてバージョンが提供されると、metadata マップに一致する API_VERSION が設定されているサービスインスタンスが検索されます。
一致するバージョンのサービスインスタンスが見つからない場合、空のインスタンスリストが返されます。この動作は、spring.cloud.load-balancer.clients.<serviceId>.api-version.fallbackToAvailableInstances を true に設定することで変更できます。これにより、API バージョンが一致するインスタンスが見つからない場合に、利用可能なすべてのインスタンスが返されるようになります。
ServiceInstanceListSupplier Bean を操作するにはデリゲートを使用します。DiscoveryClientServiceInstanceListSupplier デリゲートを使用し、それを CachingServiceInstanceListSupplier でラップして LoadBalancer キャッシュメカニズムを活用し、その結果得られる Bean を ReactiveApiVersionServiceInstanceListSupplier または BlockingApiVersionServiceInstanceListSupplier のコンストラクターに渡すことをお勧めします。 |
デフォルトでは、バージョン解析に org.springframework.web.accept.SemanticApiVersionParser を使用します。コンテキスト内で独自の ApiVersionParser または Bean を指定することで、これをオーバーライドできます。 |
Spring Cloud LoadBalancer スターター
Spring Boot アプリに Spring Cloud LoadBalancer を簡単に追加できるスターターも提供しています。これを使用するには、ビルドファイルの Spring Cloud 依存関係に org.springframework.cloud:spring-cloud-starter-loadbalancer を追加するだけです。
| Spring Cloud LoadBalancer スターターには、Spring Boot キャッシングおよびエヴィクター [GitHub] (英語) が含まれます。 |
独自の Spring Cloud LoadBalancer 構成を渡す
次のように、@LoadBalancerClient アノテーションを使用して、ロードバランサークライアントの名前と構成クラスを渡して、独自のロードバランサークライアント構成を渡すこともできます。
@Configuration
@LoadBalancerClient(value = "stores", configuration = CustomLoadBalancerConfiguration.class)
public class MyConfiguration {
@Bean
@LoadBalanced
public WebClient.Builder loadBalancedWebClientBuilder() {
return WebClient.builder();
}
} 独自の LoadBalancer 構成での作業を容易にするために、ServiceInstanceListSupplier クラスに builder() メソッドを追加しました。 |
また、spring.cloud.loadbalancer.configurations プロパティの値を zone-preference に設定して ZonePreferenceServiceInstanceListSupplier をキャッシュとともに使用するか、health-check に設定して HealthCheckServiceInstanceListSupplier をキャッシュとともに使用することにより、デフォルトの構成の代わりに代替の事前定義された構成を使用することもできます。 |
この機能を使用すると、ユーザーが作成した、またはデフォルト設定をオーバーライドするための代替手段 (たとえば ZonePreferenceServiceInstanceListSupplier) として当社が提供した ServiceInstanceListSupplier または ReactorLoadBalancer のさまざまな実装をインスタンス化できます。
カスタム構成の例はここで見ることができます。
アノテーション value 引数 (上記の例では stores ) は、指定されたカスタム構成でリクエストを送信する必要があるサービスのサービス ID を指定します。 |
次の例に示すように、@LoadBalancerClients アノテーションを介して複数の構成 (複数のロードバランサークライアント用) を渡すこともできます。
@Configuration
@LoadBalancerClients({@LoadBalancerClient(value = "stores", configuration = StoresLoadBalancerClientConfiguration.class), @LoadBalancerClient(value = "customers", configuration = CustomersLoadBalancerClientConfiguration.class)})
public class MyConfiguration {
@Bean
@LoadBalanced
public WebClient.Builder loadBalancedWebClientBuilder() {
return WebClient.builder();
}
}@LoadBalancerClient または @LoadBalancerClients 構成引数として渡すクラスは、@Configuration のアノテーションが付けられていないか、コンポーネントのスキャン範囲外である必要があります。 |
独自の構成を作成する場合、CachingServiceInstanceListSupplier または HealthCheckServiceInstanceListSupplier を使用する場合は、両方ではなくどちらか一方を使用し、ネットワーク経由でインスタンスを取得するサプライヤーの直後の階層(たとえば DiscoveryClientServiceInstanceListSupplier など)に、他のフィルタリングサプライヤーよりも前に配置するようにしてください。 |
Spring Cloud LoadBalancer ライフサイクル
カスタム LoadBalancer 構成を使用して登録すると便利な Bean の型の 1 つは LoadBalancerLifecycle です。
LoadBalancerLifecycle Bean は、onStart(Request<RC> request)、onStartRequest(Request<RC> request, Response<T> lbResponse)、onComplete(CompletionContext<RES, T, RC> completionContext) という名前のコールバックメソッドを提供します。これを実装して、ロードバランシングの前後に実行するアクションを指定する必要があります。
onStart(Request<RC> request) は Request オブジェクトをパラメーターとして受け取ります。これには、ダウンストリームクライアントのリクエストやヒントなど、適切なインスタンスを選択するために使用されるデータが含まれています。onStartRequest は、Request オブジェクトに加えて、Response<T> オブジェクトもパラメーターとして受け取ります。一方、CompletionContext オブジェクトは onComplete(CompletionContext<RES, T, RC> completionContext) メソッドに提供されます。これには、選択したサービスインスタンス、そのサービスインスタンスに対して実行されたリクエストの Status、(利用可能な場合) ダウンストリームクライアントに返されたレスポンス、(例外が発生した場合) 対応する Throwable を含む LoadBalancer Response が含まれます。
supports(Class requestContextClass, Class responseClass, Class serverTypeClass) メソッドを使用すると、問題のプロセッサーが指定された型のオブジェクトを処理するかどうかを判断できます。ユーザーによってオーバーライドされていない場合は、true を返します。
前述のメソッド呼び出しでは、RC は RequestContext 型を意味し、RES はクライアントレスポンス型を意味し、T は返されたサーバー型を意味します。 |
Spring Cloud LoadBalancer 統計
MicrometerStatsLoadBalancerLifecycle と呼ばれる LoadBalancerLifecycle Bean が提供されており、これは Micrometer を使用して負荷分散された呼び出しの統計を提供します。
この Bean をアプリケーションコンテキストに追加するには、spring.cloud.loadbalancer.stats.micrometer.enabled の値を true に設定し、MeterRegistry を使用できるようにします (たとえば、プロジェクトに Spring Boot Actuator を追加します)。
MicrometerStatsLoadBalancerLifecycle は次のメーターを MeterRegistry に登録します。
loadbalancer.requests.active: 任意のサービスインスタンスの現在アクティブなリクエストの数を監視できるゲージ (サービスインスタンスデータはタグ経由で利用可能)。loadbalancer.requests.success: 基礎となるクライアントにレスポンスを渡して終了した、負荷分散されたリクエストの実行時間を測定するタイマー。loadbalancer.requests.failed: 例外で終了した負荷分散されたリクエストの実行時間を測定するタイマー。loadbalancer.requests.discard: 破棄された負荷分散リクエスト、つまりリクエストを実行するサービスインスタンスが LoadBalancer によって取得されていないリクエストの数を測定するカウンター。
サービスインスタンス、リクエストデータ、レスポンスデータに関する追加情報は、利用可能な場合には常にタグを介してメトリクスに追加されます。
WebClient および RestClient -backed 負荷分散の場合、使用可能な場合は常に uri タグに uriTemplate を使用します。 |
spring.cloud.loadbalancer.stats.include-path を false に設定することで、path から uri タグの追加を無効にすることができます。 |
RestTemplate -backed ロードバランシングと同様に、uriTemplate にはアクセスできません。uri タグでは常にフルパスが使用されます。高カーディナリティの課題を回避するために、パスが高カーディナリティ値である場合 (たとえば、/orders/{id} で、id が多数の値を取る場合)、spring.cloud.loadbalancer.stats.include-path を false に設定して、uri タグへのパスの追加を無効にすることを強くお勧めします。 |
BlockingLoadBalancerClient などの一部の実装では、引数からジェネリクス型を確立し、型を判断してデータを読み取ることができない可能性があるため、リクエストデータとレスポンスデータが利用できない場合があります。 |
| 特定のメーターに少なくとも 1 つのレコードが追加されると、メーターはレジストリに登録されます。 |
MeterFilters を追加することで、これらのメトリクスの動作をさらに構成できます ( 公開パーセンタイルやヒストグラム (英語) の追加など)。 |
個別の LoadBalancerClients の構成
個々のロードバランサークライアントは、異なるプレフィックス spring.cloud.loadbalancer.clients.<clientId>.* を使用して個別に構成できます。clientId はロードバランサーの名前です。デフォルトの構成値は spring.cloud.loadbalancer.* 名前空間で設定でき、優先されるクライアント固有の値とマージされます。
spring:
cloud:
loadbalancer:
health-check:
initial-delay: 1s
clients:
myclient:
health-check:
interval: 30s 上記の例では、initial-delay=1s および interval=30s とマージされたヘルスチェック @ConfigurationProperties オブジェクトが生成されます。
クライアントごとの構成プロパティは、次のグローバルなプロパティを除き、ほとんどのプロパティで機能します。
spring.cloud.loadbalancer.enabled- 負荷分散をグローバルに有効または無効にしますspring.cloud.loadbalancer.retry.enabled- 負荷分散された再試行をグローバルに有効または無効にします。グローバルに有効にしても、client-prefixed プロパティを使用して特定のクライアントの再試行を無効にすることはできますが、その逆はできません。spring.cloud.loadbalancer.cache.enabled- LoadBalancer キャッシュをグローバルに有効または無効にします。グローバルに有効にした場合でも、ServiceInstanceListSupplierデリゲート階層にCachingServiceInstanceListSupplierを含まないカスタム構成を作成することで、特定のクライアントのキャッシュを無効にすることができますが、その逆はできません。spring.cloud.loadbalancer.stats.micrometer.enabled- LoadBalancer Micrometer メトリクスをグローバルに有効または無効にします
すでに使用されている場所にマップされ、clients キーワードを使用せずにクライアントごとに異なる値を指定できるプロパティ ( hints、health-check.path など) については、ライブラリの下位互換性を維持するためにその動作が維持されています。次のメジャーリリースで変更される予定です。 |
4.1.0 から、LoadBalancerProperties に callGetWithRequestOnDelegates フラグが導入されました。このフラグが true に設定されている場合、ServiceInstanceListSupplier#get(Request request) メソッドは、そのメソッドをまだ実装していない DelegatingServiceInstanceListSupplier から割り当て可能なクラスで delegate.get(request) を呼び出すように実装されます。ただし、CachingServiceInstanceListSupplier と HealthCheckServiceInstanceListSupplier は除外されます。CachingServiceInstanceListSupplier と HealthCheckServiceInstanceListSupplier は、インスタンスサプライヤー階層の直後に配置する必要があります。サプライヤーは、リクエストベースのフィルタリングが実行される前に、ネットワーク経由でインスタンスの取得を実行します。デフォルトでは true に設定されています。 |
AOT およびネイティブイメージのサポート
4.0.0 以降、Spring Cloud LoadBalancer は Spring AOT 変換とネイティブイメージをサポートします。ただし、この機能を使用するには、LoadBalancerClient サービス ID を明示的に定義する必要があります。これを行うには、@LoadBalancerClient アノテーションの value または name 属性を使用するか、spring.cloud.loadbalancer.eager-load.clients プロパティの値として使用します。
Spring HTTP サービスクライアント AutoConfiguration の LoadBalancer 統合
5.0.0 以降、Spring Cloud、LoadBalancer は、LoadBalancerRestClientHttpServiceGroupConfigurer および LoadBalancerWebClientHttpServiceGroupConfigurer を介して Spring HTTP サービスクライアント、AutoConfiguration をサポートします。
各 HTTP サービスクライアントグループについて、グループ baseUrl (spring.http.serviceclient.[groupName].base-url プロパティで定義) が null である場合、負荷分散用の serviceId ベースの URL が baseUrl として設定され、serviceId は HTTP サービスクライアント groupName から解決されます。
グループ baseUrl が null であるか、そのスキームが lb に設定されている場合、ブロッキングシナリオの場合はアプリケーションコンテキストから DeferringLoadBalancerInterceptor インスタンスが選択され、リアクティブシナリオの場合は DeferringLoadBalancerExchangeFilterFunction インスタンスが選択され、グループの RestClient.Builder または WebClient.Builder に追加され (使用可能な場合)、リクエストの負荷分散が可能になります。
例: 次の HTTP サービスクライアント構成を持つアプリの場合:
@SpringBootApplication
@ImportHttpServices(group = "verificationClient", types = {VerificationService.class,
PersonService.class})
public class HttpVerificationClientApplication {
public static void main(String[] args) {
SpringApplication.run(HttpVerificationClientApplication.class, args);
}
}spring.http.serviceclient.verificationClient.base-url プロパティが設定されていない場合、自動的に http://verificationClient に設定されます。最初はデフォルトのスキーム (http) が使用されますが、負荷分散によって安全な ServiceInstance が選択された場合は、https に変更されます。
spring.http.serviceclient.verificationClient.base-url プロパティが lb スキームを持つ URL(例: lb://verificationClient/path)に設定されている場合、http がデフォルトスキームとして初期設定され、そのスキームが使用されます。負荷分散によってセキュアな ServiceInstance が選択された場合、スキームは https に変更されます。いずれの場合も、DeferringLoadBalancerInterceptor または DeferringLoadBalancerExchangeFilterFunction のいずれかがグループのクライアントビルダーに追加され、リクエストの負荷分散が可能になります。
spring.http.serviceclient.verificationClient.base-url プロパティが、スキームが lb に設定されていない URL (たとえば、http://verificationClient/path) に設定されている場合、ロードバランサ統合は適用されません。