このページでは、Pub/Sub の 1 回限りの機能を使用してメッセージを受信して確認応答する方法について説明します。これにより、メッセージの重複処理を追跡して防止できます。この機能を有効にすると、Pub/Sub では次のセマンティックが提供されます。
サブスクライバーは、メッセージの確認応答が正常に完了したかどうかを確認できます。
メッセージの確認応答が正常に完了すると、再配信は行われません。
メッセージが未処理の間、再配信は発生しません。メッセージは、確認応答期限が切れるか、確認応答が行われるまで、未処理とみなされます。
複数の有効な配信が存在する場合は、確認応答期限の経過またはクライアントが開始した否定確認応答により、メッセージの確認応答に最新の確認応答 ID のみを使用できます。以前の確認応答 ID を持つリクエストは失敗します。
1 回限りの機能が有効になっている場合、サブスクライバーは次のガイドラインに従って、メッセージが 1 回だけ処理されるようにすることができます。
確認応答期限内にメッセージを確認応答します。
メッセージの処理が正常に確認応答されるまで、処理の進行状況に関する情報を保持します。
確認応答が失敗した場合に重複した作業を防ぐため、メッセージの処理の進行状況に関する情報を使用します。
StreamingPull API を使用するサブスクライバーを含め、pull サブスクリプション タイプのみが 1 回限りの配信をサポートします。push とエクスポートのサブスクリプションでは 1 回限りの配信はサポートされていません。
Pub/Sub では、Pub/Sub で定義された一意のメッセージ ID に基づき、クラウド リージョン内で exactly-once(1 回限り)の配信がサポートされます。
推奨されるクライアント ライブラリのバージョン
- 最適なパフォーマンスを得るには、最新バージョンのクライアント ライブラリである Python v2.13.6 以降、 Java v1.139.0 以降、 PHP v1.39.0 以降、 C# v3.2.0 以降、 C++ v2.1.0、 Go v1.25.1 以降、 Node v3.2.0 以降 および Ruby v2.12.1 以降を使用してください。
再配信と重複
想定されている再配信と予期しない再配信の違いを理解することが重要です。
再配信は、メッセージに対してクライアントによる否定確認応答が行われた場合、または確認応答期限が切れる前にクライアントが確認応答期限を延長しなかった場合のいずれかか原因で発生することがあります。再配信は有効であり、システムは意図したとおりに動作しているとみなされます。
再配信のトラブルシューティングについては、重複の処理をご覧ください。
重複とは、確認応答が成功した後、または確認応答期限が切れる前にメッセージが再送信された場合を指します。
再配信されたメッセージには、再配信の試行までの同じメッセージ ID が保持されます。
1 回限りの配信が有効になっているサブスクリプションは、重複した配信を受信しません。
クライアント ライブラリでの 1 回限りの配信のサポート
サポートされているクライアント ライブラリには、確認応答 レスポンス付き のインターフェースがあります(例: Go)。 このインターフェースを使用して、確認応答リクエストが成功したかどうかを確認できます。 確認応答リクエストが成功した場合、クライアントは再配信を受信しないことが保証されます。確認応答リクエストが失敗した場合、クライアントは再配信を想定できます。
クライアントは、確認応答インターフェースなしで、サポートされているクライアント ライブラリを使用することもできます。ただし、このような確認応答の失敗によってメッセージのサイレント再配信が生じる可能性があります。
サポートされているクライアント ライブラリには、最小 リース延長時間を設定するインターフェースがあります(例: Go)。 ネットワーク関連の確認応答の有効期限切れを回避するには、最小リース延長の値を大きな値に設定する必要があります。 最大値は 600 秒に設定されています。
Java クライアント ライブラリを使用し、サブスクライバー をカスタム gRPC チャネルで
setChannelProvider()メソッドを使用して初期化する場合は、maxInboundMetadataSizeを 1 MB 以上に設定することをおすすめします。TransportChannelProviderのビルド時この構成では、InstantiatingGrpcChannelProvider.Builder.setMaxInboundMetadataSize()またはManagedChannelBuilder.maxInboundMetadataSize()メソッドを使用できます。
1 回限りの配信に関連する変数のデフォルト値と範囲、および変数の名前は、クライアント ライブラリによって異なる場合があります。たとえば、Java クライアント ライブラリでは、次の変数が 1 回限りの配信を制御します。
| 変数 | 説明 | 値 |
|---|---|---|
setEnableExactlyOnceDelivery |
1 回限りの配信を有効または無効にします。 | true または false(デフォルト =false) |
minDurationPerAckExtension |
確認応答期限の変更に使用する最小時間(秒単位)。 | 範囲=0~600(デフォルト =none) |
maxDurationPerAckExtension |
確認応答期限の変更に使用する最大時間(秒単位)。 | 範囲=0~600(デフォルト =none) |
1 回限りの配信の場合、確認応答 ID がすでに期限切れの場合、PubASub への modifyAckDeadline または acknowledgment リクエストが失敗します。この場合、新しい配信がすでに処理中の可能性があるため、サービスは期限切れの確認応答 ID を無効と見なします。これは 1 回限りの配信の配信のための設計です。その後、acknowledgment リクエストと ModifyAckDeadline リクエストが INVALID_ARGUMENT レスポンスを返します。1 回限りの配信の配信が無効になっていると、確認応答 ID が期限切れになった場合にこれらのリクエストは OK を返します。
acknowledgment リクエストと ModifyAckDeadline リクエストに有効な確認応答 ID が含まれるようにするには、minDurationPerAckExtension の値を大きな値に設定することを検討してください。
リージョンに関する考慮事項
1 回限りの配信の保証は、サブスクライバーが同じリージョン内のサービスに接続する場合にのみ適用されます。サブスクライバー アプリケーションが複数のリージョンに分散されていると、1 回限りの配信が有効になっている場合でも、メッセージの重複配信が発生する可能性があります。パブリッシャーは任意のリージョンにメッセージを送信でき、1 回限りの保証は維持されます。
内でアプリケーションを実行すると、デフォルトで 同じリージョン内の Pub/Sub エンドポイントに接続されます。 Cloud de Confianceしたがって、 内で単一リージョンでアプリケーションを実行すると、 Cloud de Confiance 通常は単一リージョンとやり取りできます。
サブスクライバー アプリケーションを の外部または複数のリージョンで実行している場合は、Pub/Sub クライアントの構成時にロケーション エンドポイントを使用することで、単一リージョンに接続していることを保証できます。 Cloud de ConfiancePub/Sub のすべてのロケーション エンドポイントは、単一リージョンを指します。ロケーション エンドポイントの詳細については、 Pub/Sub エンドポイントをご覧ください。 Pub/Sub のすべてのロケーション エンドポイントのリストについては、 ロケーション エンドポイントのリストをご覧ください。
1 回限りの配信のサブスクリプションを作成する
コンソール、Google Cloud CLI、クライアント ライブラリ、または Pub/Sub API を使用して、1 回限りの配信を行うサブスクリプションを作成できます。 Cloud de Confiance
pull サブスクリプション
Console
1 回限りの配信を行う pull サブスクリプションを作成するには、次の手順を行います。
コンソールで [**サブスクリプション**] ページに移動します。 Cloud de Confiance
[サブスクリプションを作成] をクリックします。
[サブスクリプション ID] を入力します。
プルダウン メニューからトピックを選択するか、作成します。
サブスクリプションがトピックからメッセージを受信します。
[1 回限りの配信] セクションで、[1 回限りの配信を有効にする] を選択します。
[作成] をクリックします。
gcloud
1 回限りの配信を行う pull サブスクリプションを作成するには、--enable-exactly-once-delivery フラグを指定して gcloud pubsub subscriptions create コマンドを使用します。
gcloud pubsub subscriptions create SUBSCRIPTION_ID \ --topic=TOPIC_ID \ --enable-exactly-once-delivery
以下を置き換えます。
- SUBSCRIPTION_ID: 作成するサブスクリプションの ID
- TOPIC_ID: サブスクリプションに関連付けるトピックの ID
REST
1 回限りの配信を行うサブスクリプションを作成するには、
projects.subscriptions.create
メソッドを使用します。
PUT https://pubsub.googleapis.com/v1/projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID Authorization: Bearer $(gcloud auth print-access-token)
以下を置き換えます。
- PROJECT_ID: サブスクリプションを作成するプロジェクトのプロジェクト ID
- SUBSCRIPTION_ID: 作成するサブスクリプションの ID
1 回限りの配信を行う pull サブスクリプションを作成するには、リクエスト本文に次のように指定します。
{ "topic": "projects/PROJECT_ID/topics/TOPIC_ID", "enableExactlyOnceDelivery": true, }
以下を置き換えます。
- PROJECT_ID: トピックが含まれるプロジェクトのプロジェクト ID
- TOPIC_ID: サブスクリプションに関連付けるトピックの ID
C++
このサンプルを試す前に、クイックスタート: クライアント ライブラリの使用の C++ の設定手順を実施してください。詳細については、Pub/Sub C++ API リファレンス ドキュメントをご覧ください。
C#
このサンプルを試す前に、クイックスタート: クライアント ライブラリの使用の C# の設定手順を実施してください。詳細については、Pub/Sub C# API リファレンス ドキュメントをご覧ください。
Go
次のサンプルでは、Go Pub/Sub クライアント ライブラリのメジャー バージョン(v2)を使用します。引き続き v1 ライブラリを使用している場合は、 v2 への移行ガイドをご覧ください。 v1 コードサンプルのリストを表示するには、 非推奨のコードサンプルをご覧ください。
このサンプルを試す前に、 クイックスタート: クライアント ライブラリの使用の Go の設定手順を実施してください。 詳細については、Pub/Sub Go API のリファレンス ドキュメントをご覧ください。
Java
このサンプルを試す前に、クイックスタート: クライアント ライブラリの使用の Java の設定手順を実施してください。詳細については、Pub/Sub Java API リファレンス ドキュメントをご覧ください。
Python
このサンプルを試す前に、クイックスタート: クライアント ライブラリの使用の Python の設定手順を実施してください。詳細については、Pub/Sub Python API リファレンス ドキュメントをご覧ください。
Node.js
このサンプルを試す前に、 クイックスタート: クライアント ライブラリの使用の Node.js の設定手順を実施してください。 詳細については、Pub/Sub Node.js API リファレンス ドキュメントをご覧ください。
Node.js
このサンプルを試す前に、 クイックスタート: クライアント ライブラリの使用の Node.js の設定手順を実施してください。 詳細については、Pub/Sub Node.js API リファレンス ドキュメントをご覧ください。
Ruby
次のサンプルでは、Ruby Pub/Sub クライアント ライブラリ v3 を使用します。引き続き v2 ライブラリを使用している場合は、 v3 への移行ガイドをご覧ください。 Ruby v2 コードサンプルのリストを表示するには、 非推奨のコードサンプルをご覧ください。
このサンプルを試す前に、 クイックスタート: クライアント ライブラリの使用の Ruby の設定手順を実施してください。 詳細については、Pub/Sub Ruby API リファレンス ドキュメントをご覧ください。
PHP
このサンプルを試す前に、クイックスタート: クライアント ライブラリの使用の PHP の設定手順を実施してください。詳細については、Pub/Sub PHP API リファレンス ドキュメントをご覧ください。
1 回限りの配信サブスクリプションをモニタリングする
The
subscription/exactly_once_warning_count
指標は、再配信(有効または重複)につながる可能性のあるイベントの数を記録します。この指標は、Pub/Sub が確認応答 ID(ModifyAckDeadline リクエストまたは acknowledgment リクエスト)に関連付けられたリクエストを処理できなかった回数をカウントします。失敗の原因は、サーバーベースまたはクライアントベースの可能性があります。たとえば、1 回限りの配信情報を維持するために使用される永続性レイヤが使用できない場合、サーバーベースのイベントになります。クライアントが無効な確認応答 ID でメッセージを確認応答しようとすると、クライアント ベースのイベントになります。
指標について
subscription/exactly_once_warning_count は、実際の再配信につながる可能性がある、またはないイベントであり、クライアントの動作によってはノイズの原因となるイベントをキャプチャします。たとえば、確認応答 ID が無効な acknowledgment リクエストまたは ModifyAckDeadline リクエストを繰り返すと、指標が繰り返し増加します。
次の指標は、クライアントの動作の把握する際にも有効です。
subscription/expired_ack_deadlines_count指標は、確認応答 ID の有効期限切れの数を示します。確認応答 ID の有効期限は、ModifyAckDeadlineリクエストとacknowledgmentリクエスト両方の失敗の原因となる可能性があります。service.serviceruntime.googleapis.com/api/request_count指標を使用すると、リクエストが に到達したにもかかわらず Pub/Sub に到達しない場合のModifyAckDeadlineリクエストまたはacknowledgmentリクエストの失敗をキャプチャできます。 Cloud de Confiance by S3NS クライアントが Cloud de Confiance by S3NSから切断された場合など、この指標では キャプチャできない障害があります。
再試行可能な障害イベントでは、ほとんどの場合、サポートされているクライアント ライブラリによってリクエストが自動的に再試行されます。
割り当て
1 回限りの配信サブスクリプションには、追加の割り当て要件が適用されます。これらの割り当ては、次のものに適用されます。
- 1 回限りの配信が有効になっているサブスクリプションから消費されたリージョンごとのメッセージ数。
- 1 回限りの配信が有効になっているサブスクリプションを使用する場合に、確認応答済みのメッセージまたは期限が延長されたメッセージのリージョンごとの数。
これらの割り当ての詳細については、 割り当てトピックの表をご覧ください。
1 回限りの配信と順序指定サブスクリプション
Pub/Sub では、順序付けられた配信による 1 回限りの配信がサポートされています。
1 回限りの配信で順序指定を使用する場合、Pub/Sub は確認応答が順番に行われることを想定しています。確認応答が順不同である場合、サービスへのリクエストは一時的なエラーによって失敗します。配信に対する正しい確認応答が行われる前に確認応答期限が切れると、クライアントはメッセージの再配信を受け取ります。そのため、1 回限りの配信で順序指定を使用する場合、クライアントのスループットは 1 秒あたり数千件のメッセージに制限されます。
1 回限りの配信と push サブスクリプション
Pub/Sub は、pull サブスクリプションでのみ 1 回限りの配信をサポートします。
push サブスクリプションからのメッセージを使用するクライアントは、push リクエストに正常なレスポンスで応答することによってメッセージの確認応答を行います。しかし、クライアントには、Pub/Sub サブスクリプションがレスポンスを受信して処理したかどうかはわかりません。これは、クライアントによって確認応答リクエストが開始され、リクエストが正常に処理されると Pub/Sub サブスクリプションが応答する pull サブスクリプションと異なります。このため、1 回限りの配信セマンティクスは、push サブスクリプションと一致しません。
知っておくべきこと
CreateSubscription で確認応答期限が指定されていない場合、1 回限りの配信が有効になっているサブスクリプションには、60 秒のデフォルトの確認応答期限が設定されます。
デフォルトの確認応答期限が長いほど、ネットワーク イベントによる再配信を回避できる可能性が高まります。サポートされているクライアント ライブラリでは、デフォルトのサブスクリプション確認応答期限は使用されません。
1 回限りの配信サブスクリプションでは、通常のサブスクリプションよりもパブリッシュ/サブスクライブ間のレイテンシが大幅に高くなります。
高スループットが必要な場合は、1 回限りの配信クライアントでもストリーミング pull を使用する必要があります。
1 回限りの配信が有効になっていても、パブリッシュ側の重複によって、サブスクリプションが同じメッセージの複数のコピーを受信する場合があります。パブリッシュ側の重複は、パブリッシュを行うクライアントまたは Pub/Sub サービスによる複数の一意のパブリッシュの再試行が原因で発生する可能性があります。再試行を複数回実施する際にパブリッシュを行うクライアントが複数回の一意のパブリッシュを行うと、異なる メッセージ ID を持つ再配信につながります。クライアントのパブリッシュ リクエストに応答するための Pub/Sub サービスによる複数回の一意のパブリッシュが、同じ メッセージ ID を持つ再配信につながります。
subscription/exactly_once_warning_countのエラーは再試行できます。サポートされているクライアント ライブラリは、これらのエラーを自動的に再試行します 。ただし、無効な確認応答 ID に関連するエラーは再試行できません。