pull サブスクリプションのトラブルシューティング

このドキュメントでは、Pub/Sub の pull サブスクリプションに関する一般的なトラブルシューティングのヒントを示します。pull サブスクリプションの詳細については、pull サブスクライバー ガイドをご覧ください。

Pub/Sub サブスクリプションを効果的にモニタリングするには、まず配信レイテンシの健全性スコアsubscription/delivery_latency_health_score)を確認して、予期しないレイテンシやレイテンシの増加に貢献している要因を確認することをおすすめします。

最も古い未確認メッセージの経過時間が長くなる

oldest_unacked_message_age は、Pub/Sub サブスクリプションの健全性をモニタリングするための重要な指標です。サブスクライバーによって確認応答(ACK)されていない、サブスクリプションのバックログ内の最も古いメッセージの経過時間(秒単位)を測定します。この指標は、処理の遅延やボトルネックの可能性に関する有益な分析情報を提供します。

メッセージのバックログをモニタリングすることで、タイムリーで効率的なメッセージ処理が実現します。確認応答されていない最も古いメッセージの経過時間をトラッキングすることで、コンシューマが遅れている状況を事前に特定できます。これにより、パフォーマンスの低下に関する潜在的な問題に早期に対応できます。

調査できる一般的なバックログの問題には、次のようなものがあります。

クライアントの構成に関する問題

oldest_unacked_message_age 指標と num_undelivered_messages 指標の両方が同時に増加している場合は、サブスクライバーがメッセージの量についていけていない可能性があります。この場合、定期購入コンポーネントに焦点を当てて調査します。

  • クライアントの健全性: サブスクライバー クライアントをホストするマシンのリソース使用率(CPU、メモリ、ネットワーク帯域幅など)を分析します。処理効率を阻害する可能性のある問題点を確認します。

  • クライアント コード: 最近のコード変更を確認し、エラーログを調べます。サブスクライバー コードのバグや非効率性により、メッセージ処理速度が大幅に低下する可能性があります。なお、特定のメッセージで問題が発生する可能性があります。たとえば、複数のメッセージがデータベース内の同じ行に同時にアクセスする必要がある場合があります。この動作により、競合とレイテンシの増加が発生する可能性があります。

  • 割り当ての上限: ホスティング サービスによって課せられる Pub/Sub の割り当てや上限を超えていないことを確認します。サブスクライバーが Google Cloud でホストされている場合は、Compute Engine または GKE のリソース割り当てを確認し、ボトルネックの発生を防ぎます。

サブスクライバーがメッセージを否定応答した

サブスクライバーがメッセージを否定応答(nack)すると、メッセージが正常に処理されなかったことを Pub/Sub に通知します。Pub/Sub は、同じメッセージを再配信しようとします。メッセージの nack が繰り返されると、重複が発生し、メッセージの配信が大幅に遅れる可能性があります。

メッセージをナックしても、次の pull で別のメッセージが取得されるとは限りません。Pub/Sub の再配信ポリシーにより、新しいメッセージよりも先に、nack されたメッセージが再配信される場合があります。したがって、特定のメッセージをフィルタリングまたはスキップする方法として nack に依存しないでください。代わりに、再試行ポリシー(できれば指数バックオフ)を設定して、後で処理できる可能性が高いが再配信までに少し時間のかかる個々のメッセージをバックオフします。

特定のメッセージを意図的にスキップする必要がある場合は、処理しない場合でも、そのメッセージを ack することをおすすめします。これにより、それらのアイテムはサブスクリプションから削除され、不要な再配信が回避され、リソースの消費が削減されます。意図的かどうかにかかわらず、メッセージを未確認のままにすると、バックログの問題と重複配信が発生します。

配信レイテンシが高い

Pub/Sub の配信レイテンシは、パブリッシャーからのメッセージがサブスクライバーに届くまでの時間です。配信レイテンシが長くなる原因として、次のことが考えられます。

チャンネル登録者が少ない

StreamingPull を使用するクライアントの場合、常に低レイテンシを実現するには、サブスクリプションに対する複数のオープン StreamingPull 接続を維持します。有効なサブスクライバー接続がないと、Pub/Sub はメッセージを迅速に配信できません。単一のストリームが単一障害点となり、遅延のリスクが高まる可能性があります。指標 subscription/open_streaming_pulls を使用すると、アクティブなストリーミング接続の数を把握できます。これにより、受信メッセージを処理するのに十分なストリームが常に確保されます。

単項 pull を使用するクライアントの場合、常に低レイテンシを実現するには、サブスクリプションに対する未処理の pull リクエストを複数保持します。リクエストが頻繁に行われないと、バックログにメッセージが蓄積され、レイテンシが増加する可能性があります。このアプローチにより、接続性のギャップを最小限に抑え、配信のレイテンシを改善できます。

高レベルのクライアント ライブラリは、運用のオーバーヘッドと処理コストを最小限に抑えながら、高スループットと低レイテンシを必要とする場合におすすめします。デフォルトでは、高レベル クライアント ライブラリは StreamingPull API を使用します。これは、レイテンシを最小限に抑えるには適切な選択であるためです。高レベル クライアント ライブラリには、認証、スループット、レイテンシの最適化、メッセージのフォーマットなどの機能のために基盤となる API 呼び出しを処理するビルド済み関数とクラスが含まれています。

クライアントの構成に関する問題

クライアント構成の問題をご覧ください。

バックログが多い

Pub/Sub サブスクリプションの未確認メッセージのメッセージ バックログは、メッセージがサブスクライバーによってすぐに処理されないため、エンドツーエンドのレイテンシが本質的に増加します。

順序指定キーと 1 回限りの配信

順序付けキーと 1 回限りの配信は有用な機能ですが、正しい配信を確実に行うには、Pub/Sub 内で追加の調整が必要になります。この調整により、可用性が低下し、レイテンシが増加する可能性があります。定常状態では差異は最小限ですが、必要な調整手順を行うと、一時的にレイテンシが増加したり、エラー率が増加したりする可能性があります。順序指定が有効になっている場合、同じ順序指定キーを持つ前のメッセージが ACK されるまで、順序指定キーを持つメッセージは配信されません。

メッセージの順序付けや 1 回限りの配信がアプリケーションに不可欠かどうかを検討します。低レイテンシが最優先の場合は、これらの機能の使用を最小限に抑えることで、メッセージ処理の遅延を減らすことができます。

メッセージ サイズの増加

メッセージ サイズが急増すると、Pub/Sub とクライアントとの間の転送時間が長くなり、クライアント側でのメッセージの処理時間が長くなる可能性があります。

配信レイテンシの増加が確認された場合は、topic_id でグループ化された topic/message_sizes 指標を使用してメッセージサイズを確認できます。メッセージサイズの急増と、検出されたパフォーマンスの問題を関連付けます。

メッセージが見つからない

メッセージがサブスクライバーに正常に配信されていないと思われる場合は、次のいずれかの理由が原因である可能性があります。

複数のコンシューマを使用する Pub/Sub サブスクリプションでのメッセージ配信

Pub/Sub では、メッセージがコンシューマ間で不均一に分散される可能性があります。この動作は、Pub/Sub が効率性を高めるためにアクティブなコンシューマにメッセージを分散するため発生します。1 つのコンシューマが想定よりも少ないメッセージ数を受信したり、他のコンシューマとは異なるメッセージのサブセットを受信したりすることがあります。

メッセージはすでにクライアントに届いている可能性があり、未確認のメッセージのバックログがあるからといって、必ずしも次の pull リクエストでそれらのメッセージを受け取れるとは限らないことに注意してください。コンシューマは、Google Cloud コンソールまたは Google Cloud CLI で pull を使用するユーザーや、ローカルでカスタム サブスクライバーを実行してメッセージを確認するユーザーである可能性があります。

単項 pull クライアントの場合、一部の pull リクエストでメッセージが 0 個返されることがあります。サブスクライバーが足りないセクションで説明したように、一部のリクエストでは、構成された最大メッセージ数より少ないメッセージが返される場合や、メッセージが返されない場合があるため、未処理の pull リクエストを複数保持することをおすすめします。

このような動作が疑われる場合は、サブスクリプションに複数のコンシューマが同時に接続されているかどうかを調査し、確認します。

サブスクリプションでフィルタする

サブスクリプションにフィルタが適用されているかどうかを確認します。その場合、フィルタに一致するメッセージのみを受信します。Pub/Sub サービスは、フィルタに一致しないメッセージの確認応答を自動的に行います。フィルタがバックログ指標に与える影響について検討してください。

オプション returnImmediately を使用する

クライアントが単項 Pull を使用している場合は、returnImmediately フィールドが true に設定されているかどうかを確認します。これは非推奨のフィールドで、メッセージが返されなくても pull リクエストにすぐに応答するように Pub/Sub サービスに指示します。その結果、バックログがある場合でも、pull リクエストが 0 件のメッセージで返されることがあります。

重複への対処

Pub/Sub でのメッセージの重複は、サブスクライバーが確認応答期限内にメッセージを確認応答できない場合によく発生します。これにより、メッセージが再配信され、重複しているように見えることがあります。サブスクライバーが確認応答期限に間に合わないレートは、subscription/expired_ack_deadlines_count 指標を使用して測定できます。詳しくは、確認期限の有効期限のモニタリングをご覧ください。

メッセージの期限を延長すると、重複率を低下させることができます。

  • 期限の延長はクライアント ライブラリによって自動的に処理されますが、構成可能な延長期限の最大値にはデフォルトの上限があります。
  • 独自のクライアント ライブラリを構築する場合は、modifyAckDeadline メソッドを使用して、確認応答期限を延長します。

サブスクライバーでメッセージが処理されて ACK されるよりも速く pull されると、一部のメッセージが期限切れになり、期限の延長が必要になる場合があります。ただし、定期購入者が引き続き負担を感じている場合、期限の延長を繰り返しても最終的には失敗します。最悪のシナリオでは、重複するチャンネル登録者数が上限を超え、バックログが悪化する可能性があります。期限切れの重複を削除し、新しい重複を生成します。

サブスクライバーに負荷をかけないように、サブスクライバーが一度に pull するメッセージの数を減らします。これにより、サブスクライバーが期限内に処理するメッセージの数を減らすことができます。期限切れになるメッセージと再配信されるメッセージが少なくなります。

サブスクライバーが一度に pull するメッセージ数を減らすには、サブスクライバーのフロー制御構成で未処理のメッセージの最大数を減らす必要があります。万能な値はないため、スループットとサブスクライバーの容量に基づいて最大未処理メッセージ数の上限を調整する必要があります。各アプリケーションがメッセージを異なる方法で処理し、メッセージの ACK にかかる時間も異なることを考慮してください。

再試行を強制する

Pub/Sub にメッセージの再試行を強制するには、nack リクエストを送信します。高レベルのクライアント ライブラリを使用していない場合は、ackDeadlineSeconds を 0 に設定して modifyAckDeadline リクエストを送信します。

順序指定キー

Pub/Sub が順序指定キーを含むメッセージを再配信する場合、以前に確認応答済みだった場合でも、同じ順序指定キーを持つ後続のメッセージもすべて再配信します。これは、シーケンスの順序を維持するためです。ただし、依存メッセージがシーケンス内の前のメッセージの正常な受信後にのみ送信されることは厳密には保証されません。

サブスクライバーがメッセージを否定応答している

サブスクライバーがメッセージを否定応答しているをご覧ください。

StreamingPull サブスクリプションのトラブルシューティング

リクエスト レイテンシ指標とエンドツーエンドの配信レイテンシの関係

StreamingPull の場合、指標 serviceruntime.googleapis.com/api/request_latencies はストリームが開いている時間を表します。この指標は、エンドツーエンドの配信レイテンシの特定には役立ちません。

リクエスト レイテンシ指標を使用する代わりに、配信レイテンシの健全性スコアを使用して、エンドツーエンドの配信レイテンシの増加に寄与している要因を確認します。

StreamingPull 接続が OK 以外のステータスで終了する

StreamingPull ストリームは、常に OK 以外のステータスで終了します。単一 RPC のエラー ステータスとは異なり、StreamingPull のこのステータスは、ストリームが切断されたことを示しています。リクエストは失敗していません。そのため、StreamingPull API のエラー率が 100% にもなることがありますが、この動作は設計によるものです。

StreamingPull ストリームは常にエラーで終了するため、エラーの診断中にストリーム終了の指標を調べることは役に立ちません。代わりに、response_code または response_class でグループ化された StreamingPull レスポンス指標 subscription/streaming_pull_response_count に注目してください。

次のエラーを探します。

  • サブスクリプション バックログに無効な Cloud KMS 鍵で暗号化されたメッセージがある場合、前提条件の失敗エラーが発生することがあります。プルを再開するには、鍵へのアクセスを復元します。

  • Pub/Sub でリクエストを処理できないときに発生する可能性のある使用不可のエラー。これは一時的な状態である可能性が高く、クライアント ライブラリはリクエストを再試行します。クライアント ライブラリを使用している場合は、ご対応いただく必要はありません。

  • 存在しないエラーは、サブスクリプションが削除された場合、またはサブスクリプションが最初から存在しなかった場合に発生する可能性があります。後者のケースは、無効なサブスクリプション パスを指定した場合に発生します。

その他の関連情報