Stork リファレンスガイド
このガイドは、 Stork 入門ガイドと対です。QuarkusでのSmallRye Stork統合の設定と使用方法について説明しています。
この技術は、previewと考えられています。 preview では、下位互換性やエコシステムでの存在は保証されていません。具体的な改善には設定や API の変更が必要になるかもしれませんが、 stable になるための計画は現在進行中です。フィードバックは メーリングリスト や GitHub の課題管理 で受け付けています。 とりうるステータスの完全なリストについては、 FAQの項目 を参照してください。 |
対応クライアント
現在のStork統合で対応しているのは次の通りです:
-
リアクティブRESTクライアント
-
gRPCクライアント
注意: gRPCクライアント統合は、統計ベースのロードバランサーをサポートしていません。
利用可能なサービスディスカバリーと選択
提供されるサービスディスカバリーと選択については、 SmallRye Storkのウェブサイトをご確認ください。
KubernetesでのStorkの使用
Storkは、Kubernetesがデフォルトで提供しているものを超える、Kubernetesのサービスディスカバリーサポートを提供します。これは、KubernetesのサービスをバックアップしているすべてのPodを探しますが、Kubernetesのようにラウンドロビンを適用するのではなく、Storkのロードバランサーを使用してポッドを選択するオプションを提供します。
この機能を使用するには、プロジェクトに以下の依存関係を追加します。
<dependency>
<groupId>io.smallrye.stork</groupId>
<artifactId>stork-service-discovery-kubernetes</artifactId>
</dependency>
implementation("io.smallrye.stork:stork-service-discovery-kubernetes")
Kubernetes Serviceとして公開される予定の各サービスについて、ルックアップを設定します。
quarkus.stork.my-service.service-discovery.type=kubernetes
quarkus.stork.my-service.service-discovery.k8s-namespace=my-namespace
Storkは、指定された名前(前の例では my-service
)のKubernetes Serviceを指定された名前空間で探します。StorkはKubernetes ServiceのIPを直接使用し、選択とバランシングをKubernetesに任せるのではなく、サービスを検査し、サービスを提供しているポッドのリストを取得します。そして、インスタンスを選択することができます。
KubernetesでStorkを使う詳しい例は、 Kubernetes で Stork を使用 をお読みください。
カスタムサービスディスカバリーの実装
Storkは拡張性があり、独自のサービスディスカバリーメカニズムを実装することができます。
依存関係
サービス ディスカバリー プロバイダーを実装するには、プロジェクトが Core と Configuration Generator に依存していることを確認してください。前者はカスタムディスカバリーの実装に必要なクラスを提供し、後者はStorkが必要とするクラスを生成するアノテーションプロセッサを含んでいます。
<dependency>
<groupId>io.smallrye.stork</groupId>
<artifactId>stork-core</artifactId>
</dependency>
<dependency>
<groupId>io.smallrye.stork</groupId>
<artifactId>stork-configuration-generator</artifactId>
<!-- provided scope is sufficient for the annotation processor -->
<scope>provided</scope>
</dependency>
implementation("io.smallrye.stork:stork-core")
compileOnly("io.smallrye.stork:stork-configuration-generator")
プロバイダがエクステンションに配置されている場合、設定ジェネレータは実行時モジュールの
|
サービスディスカバリープロバイダーの実装
カスタムプロバイダーは、このサービスディスカバリープロバイダーを使用して設定されたサービスごとに io.smallrye.stork.ServiceDiscovery
インスタンスを作成するファクトリーです。例えば acme
のようなタイプが各プロバイダを識別します。このタイプは、設定でプロバイダーを参照するために使用されます。
quarkus.stork.my-service.service-discovery.type=acme
最初のステップは、 io.smallrye.stork.spi.ServiceDiscoveryProvider
インターフェースの実装です。
package examples;
import io.smallrye.stork.api.ServiceDiscovery;
import io.smallrye.stork.api.config.ServiceConfig;
import io.smallrye.stork.api.config.ServiceDiscoveryAttribute;
import io.smallrye.stork.api.config.ServiceDiscoveryType;
import io.smallrye.stork.spi.StorkInfrastructure;
import io.smallrye.stork.spi.ServiceDiscoveryProvider;
@ServiceDiscoveryType("acme") (1)
@ServiceDiscoveryAttribute(name = "host",
description = "Host name of the service discovery server.", required = true) (2)
@ServiceDiscoveryAttribute(name = "port",
description = "Port of the service discovery server.", required = false)
public class AcmeServiceDiscoveryProvider (3)
implements ServiceDiscoveryProvider<AcmeConfiguration> {
(4)
@Override
public ServiceDiscovery createServiceDiscovery(AcmeConfiguration config,
String serviceName,
ServiceConfig serviceConfig,
StorkInfrastructure storkInfrastructure) {
return new AcmeServiceDiscovery(config);
}
}
この実装は単純です。
1 | @ServiceDiscoveryType アノテーションは、サービスディスカバリープロバイダーのタイプを定義します。このアノテーションでアノテーションされた各 ServiceDiscoveryProvider に対して、設定クラスが生成されます。構成クラスの名前は、プロバイダの名前に Configuration を付加して構成されます。 |
2 | このサービスディスカバリープロバイダーで構成されたサービスの設定プロパティを定義するには、 @ServiceDiscoveryAttribute を使用します。設定プロパティは、フォームのすべてのプロパティから次の形で収集されます: stork.my-service.service-discovery.attr=value . |
3 | The provider needs to implement ServiceDiscoveryType typed by the configuration class. This configuration class is generated automatically by the Configuration Generator. Its name is created by appending Configuration to the service discovery type, such as AcmeConfiguration . |
4 | createServiceDiscovery メソッドは、ファクトリーメソッドです。このメソッドは、設定を受け取り、サービスの名前と利用可能なインフラへのアクセスを行います。 |
次に、 ServiceDiscovery
インターフェースを実装する必要があります。
package examples;
import java.util.Collections;
import java.util.List;
import io.smallrye.mutiny.Uni;
import io.smallrye.stork.api.ServiceDiscovery;
import io.smallrye.stork.api.ServiceInstance;
import io.smallrye.stork.impl.DefaultServiceInstance;
import io.smallrye.stork.utils.ServiceInstanceIds;
public class AcmeServiceDiscovery implements ServiceDiscovery {
private final String host;
private final int port;
public AcmeServiceDiscovery(AcmeConfiguration configuration) {
this.host = configuration.getHost();
this.port = Integer.parseInt(configuration.getPort());
}
@Override
public Uni<List<ServiceInstance>> getServiceInstances() {
// Proceed to the lookup...
// Here, we just return a DefaultServiceInstance with the configured host and port
// The last parameter specifies whether the communication with the instance should happen over a secure connection
DefaultServiceInstance instance =
new DefaultServiceInstance(ServiceInstanceIds.next(), host, port, false);
return Uni.createFrom().item(() -> Collections.singletonList(instance));
}
}
繰り返しになりますが、この実装は単純過ぎるものです。一般的には、設定から得た値でサービス・インスタンスを作成するのではなく、サービス・ディスカバリー・バックエンドに接続してサービスを探し、それに応じてサービス・インスタンスのリストを作成します。これが、このメソッドが Uni
を返す理由です。ほとんどの場合、ルックアップはリモート操作で行われます。
カスタムサービス選択/ロードバランサーの実装
Storkは拡張性があり、独自のサービス選択(ロードバランサー)機構を実装することができます。
依存関係
ロードバランサープロバイダーを実装するには、プロジェクトが Core と Configuration Generator に依存していることを確認してください。前者はカスタムロードバランサーの実装に必要なクラスを提供し、後者はStorkが必要とするクラスを生成するアノテーションプロセッサを含んでいます。
<dependency>
<groupId>io.smallrye.stork</groupId>
<artifactId>stork-core</artifactId>
</dependency>
<dependency>
<groupId>io.smallrye.stork</groupId>
<artifactId>stork-configuration-generator</artifactId>
<!-- provided scope is sufficient for the annotation processor -->
<scope>provided</scope>
</dependency>
implementation("io.smallrye.stork:stork-core")
compileOnly("io.smallrye.stork:stork-configuration-generator")
カスタム ディスカバリー プロバイダと同様に、プロバイダがエクステンションに配置されている場合は、ランタイム モジュールの |
ロードバランサー・プロバイダーの実装
ロードバランサーの実装は3つの要素で構成されています:
-
LoadBalancer
Stork サービスのサービスインスタンスを選択する責任があります。 -
LoadBalancerProvider
ロードバランサーの type に応じてLoadBalancer
のインスタンスを作成します。 -
ロードバランサーの設定である
LoadBalancerProviderConfiguration
type は、例えば acme
のように、各プロバイダーを識別します。この type は、設定でプロバイダーを参照するために使用されます。
quarkus.stork.my-service.load-balancer.type=acme
ServiceDiscoveryProvider
と同様に、LoadBalancerProvider
の実装は type を定義する @LoadBalancerType
のアノテーションが必要です。プロバイダーが期待する設定プロパティは、プロバイダーに置かれた @LoadBalancerAttribute
のアノテーションで定義する必要があります。
package examples;
import io.smallrye.stork.api.LoadBalancer;
import io.smallrye.stork.api.ServiceDiscovery;
import io.smallrye.stork.api.config.LoadBalancerAttribute;
import io.smallrye.stork.api.config.LoadBalancerType;
import io.smallrye.stork.spi.LoadBalancerProvider;
@LoadBalancerType("acme")
@LoadBalancerAttribute(name = "my-attribute",
description = "Attribute that alters the behavior of the LoadBalancer")
public class AcmeLoadBalancerProvider implements
LoadBalancerProvider<AcmeLoadBalancerProviderConfiguration> {
@Override
public LoadBalancer createLoadBalancer(AcmeLoadBalancerProviderConfiguration config,
ServiceDiscovery serviceDiscovery) {
return new AcmeLoadBalancer(config);
}
}
なお、 ServiceDiscoveryProvider
と同様に、 LoadBalancerProvider
インターフェースもパラメータとして設定クラスを受け取ります。この設定クラスは、 Configuration Generator によって自動的に生成されます。その名前は、プロバイダークラスの名前に Configuration
を付加して作成されます。
次のステップは、 LoadBalancer
インターフェースを実装することです。
package examples;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Random;
import io.smallrye.stork.api.LoadBalancer;
import io.smallrye.stork.api.NoServiceInstanceFoundException;
import io.smallrye.stork.api.ServiceInstance;
public class AcmeLoadBalancer implements LoadBalancer {
private final Random random;
public AcmeLoadBalancer(AcmeLoadBalancerProviderConfiguration config) {
random = new Random();
}
@Override
public ServiceInstance selectServiceInstance(Collection<ServiceInstance> serviceInstances) {
if (serviceInstances.isEmpty()) {
throw new NoServiceInstanceFoundException("No services found.");
}
int index = random.nextInt(serviceInstances.size());
return new ArrayList<>(serviceInstances).get(index);
}
}
繰り返しになりますが、この実装は単純過ぎるもので、受信したリストからランダムにインスタンスを選択するだけです。
examples.AcmeLoadBalancerProvider