クライアント ライブラリのインスタンスは再利用可能で、長期間使用できるように設計されています。通常、アプリケーションはリクエストごとにライブラリを作成するのではなく、クライアント ライブラリの単一のインスタンスを保持します。
Java-KMS を例として、次のスニペットは同じクライアント インスタンスで呼び出される複数のリクエストを示しています。
// Create one instance of KMS's KeyManagementServiceClient
KeyManagementServiceClient keyManagementServiceClient =
KeyManagementServiceClient.create();
keyManagementServiceClient.listKeyRings();
keyManagementServiceClient.asymmetricSign();
keyManagementServiceClient.createCryptoKey();
// ... other code ...
// Create one instance of KMS's AutokeyClient
AutokeyClient autokeyClient = AutokeyClient.create();
autokeyClient.listKeyHandles();
autokeyClient.getKeyHandle();
クライアントを閉じる
クライアントのライフサイクルを管理する方法は、ユースケースと特定のクライアント ライブラリによって異なります。たとえば、フレームワークを使用している場合は、クライアント管理に関するフレームワークのガイドラインに従ってください。シナリオによっては、存続期間の短いクライアントに try-with-resources を使用する場合がありますが、一般的には、効率を高めるために存続期間の長いクライアント インスタンスを再利用することをおすすめします。
クライアントで close() を呼び出すと、正常にシャットダウンされ、既存のタスクが完了するまで続行されます。クライアントは新しいタスクを受け入れません。クライアントを閉じないと、そのリソースが保持され、アプリケーションでメモリリークが発生します。
次の例では、Java-KMS を使用してクライアントを閉じる方法を示します。
KeyManagementServiceClient keyManagementServiceClient =
KeyManagementServiceClient.create(keyManagementServiceSettings);
// ... other code ...
keyManagementServiceClient.close();
// For gRPC clients, it's recommended to call awaitTermination to ensure a
// graceful shutdown and avoid the following error message in the logs:
// ERROR i.g.i.ManagedChannelOrphanWrapper - *~*~*~ Channel ManagedChannelImpl
// was not shutdown properly!!! ~*~*~*
// java.lang.RuntimeException: ManagedChannel allocation site
// at io.grpc.internal.ManagedChannelOrphanWrapper$ManagedChannelReference.<init>
keyManagementServiceClient.awaitTermination(DURATION, TimeUnit.SECONDS);
// Optionally include a shutdownNow() call after awaitTermination() to force
// close any lingering resources
keyManagementServiceClient.shutdownNow();
close() に加えて、一部の Java クライアント ライブラリには、クライアントのライフサイクルを管理するための関連メソッドがいくつか用意されています。
shutdown():close()と同じです。shutdownNow(): シャットダウン プロセスを直ちに呼び出します。実行中のすべてのタスクを停止し、タスクが完了するまで待機しません。isShutdown(): バックグラウンド タスクがシャットダウンされている場合はtrueを返します。isTerminated(): シャットダウン後にすべてのタスクが完了した場合はtrueを返します。awaitTermination(): シャットダウン後にすべての作業が完了するまで、指定された時間だけブロックします。
複数のクライアントを使用するケース
クライアント ライブラリの複数のインスタンスを共存させる必要がある特定のユースケースがあります。複数のクライアントを使用する主なユースケースは、複数の異なるエンドポイントに送信する必要があるリクエストがある場合です。 クライアント インスタンスは単一のエンドポイントに接続します。複数のエンドポイントに接続するには、それぞれにクライアントを作成します。
マルチクライアントのリスク
複数のクライアント ライブラリ インスタンスを使用するアプリケーションには、次のような一般的なリスクがあります。
- メモリリークの可能性の増加。すべてのクライアント インスタンスが適切に閉じられていない場合、リソースが残ります。
- パフォーマンスへの影響。複数の gRPC チャネルを初期化するとパフォーマンス コストが発生し、パフォーマンスが重視されるアプリケーションではコストが増加する可能性があります。
- 処理中のリクエストに関する問題。リクエストが処理中のときにクライアントを閉じると、
RejectedExecutionExceptionが発生する可能性があります。クライアントを閉じる前に、リクエストが完了していることを確認してください。