イベントが不承認になる理由は複数あります。たとえば、停止によりイベント受信サービスが一時的に利用できなくなる場合や、イベントの処理中にサービスでエラーが発生する場合、またはサービス リソースが不足する場合があります。このような一時的なエラーは再試行できます。
イベントがイベント受信者に配信されないこともあります。たとえば、イベントが構成された想定のスキーマと一致しない場合や、イベント メッセージが最終的な宛先に転送される前にイベントのメディエーションに失敗する場合があります。このような場合、永続的なエラーが発生します。
一時的なエラー
Eventarc Advanced には、一時的なエラーを処理する機能が用意されています。これらの一時的なエラーは再試行できます。これらのエラーには、次のエラーコードが含まれます。
- HTTP
408 Request Timeout
- HTTP
409 Conflict
- HTTP
429 Too Many Requests
- HTTP
500 Internal Server Error
- HTTP
502 Bad Gateway
- HTTP
503 Service Unavailable
- HTTP
504 Gateway Time-out
永続的なエラー
一時的なエラーとは対照的に、永続的なエラーには次のものがあります。
- 構成された再試行回数が使い果たされたときに発生するエラー
- イベントが宛先に転送される前に失敗したときに発生するエラー
- 再試行できないと見なされるエラーコードが返されるエラー(一時的なエラーに記載されているエラーコード以外など)
永続的なエラーを手動で特定して適切に処理できます。
一時的なエラーを再試行する
Eventarc Advanced は、再試行可能なエラーを処理するために指数バックオフ遅延を使用します。デフォルトの再試行ポリシーでは、1 秒の遅延から始まり、失敗した試行ごとに遅延が 2 倍になります(最大 60 秒、最大 5 回)。
デフォルトの再試行ポリシーは、Google Cloud コンソールまたは gcloud beta eventarc pipelines update
コマンドを使用して変更できます。
デフォルトのバックオフ係数 2
は変更できません。
コンソール
Google Cloud コンソールで、[Eventarc] > [パイプライン] ページに移動します。
パイプラインの名前をクリックします。
[パイプラインの詳細] ページで、[編集] をクリックします。
[パイプラインの編集] ページの [再試行ポリシー] セクションで、次のフィールドを変更します。
- Max attempts: 再試行回数。デフォルトは
5
回です。任意の正の実数にできます。1
に設定した場合、再試行ポリシーは適用されず、メッセージの配信は 1 回だけ試行されます。 - 最小遅延時間(秒): 初期遅延時間(秒)。デフォルトは
1
秒です。1
~600
の範囲で指定してください。 - 最大遅延時間(秒): 最大遅延時間(秒)。デフォルトは
60
秒です。1
~600
の範囲で指定してください。
最小遅延と最大遅延を同じ値に設定すると、リニア バックオフを構成できます。
- Max attempts: 再試行回数。デフォルトは
[保存] をクリックします。
gcloud
gcloud beta eventarc pipelines update PIPELINE_NAME \
--min-retry-delay=MIN_DELAY \
--max-retry-delay=MAX_DELAY \
--max-retry-attempts=MAX_ATTEMPTS
次のように置き換えます。
PIPELINE_NAME
: パイプラインの ID または完全修飾識別子。MIN_DELAY
: 初期遅延(秒単位)。デフォルトは1
秒です。1
~600
の範囲で指定してください。MAX_DELAY
: 最大遅延時間(秒)。デフォルトは60
秒です。1
~600
の範囲で指定してください。MAX_ATTEMPTS
: 再試行回数。デフォルトは5
回です。任意の正の実数を指定できます。1
に設定した場合、再試行ポリシーは適用されず、メッセージの配信は 1 回だけ試行されます。
次の例では、最小遅延と最大遅延を同じ値に設定して、リニア バックオフを構成します。
gcloud beta eventarc pipelines update my-pipeline \
--min-retry-delay=4 \
--max-retry-delay=4 \
--max-retry-attempts=5
メールをアーカイブして永続的なエラーを処理する
受信時に BigQuery テーブルにメッセージを書き込むことができます。これにより、永続的なエラーを手動で特定し、適切に処理できます。
次のセクションでは、イベント メッセージをアーカイブし、永続的なエラーを特定して、影響を受けるイベントを再試行するために必要な手順の概要について説明します。
- バスを作成します。バスを適切に構成します(Google ソースからイベントを公開するなど)。
- Pub/Sub トピックを作成する。この Pub/Sub トピックがパイプラインのターゲット デスティネーションになります。
- Pub/Sub トピックの BigQuery サブスクリプションを作成します。BigQuery サブスクリプションは、受信時に既存の BigQuery テーブルにメッセージを書き込むエクスポート サブスクリプションの一種です。また、BigQuery サブスクリプションの作成時にテーブルを作成することもできます。
バスが受信したすべてのメッセージを(
--cel-match="true"
を使用して)Pub/Sub トピックに転送するパイプラインと登録を作成します。パイプラインの再試行ポリシーを構成します。たとえば、次のコマンドはパイプラインと登録を作成します。
gcloud beta eventarc pipelines create my-archive-pipeline \ --destinations=pubsub_topic='my-archive-topic',network_attachment='my-network-attachment' \ --min-retry-delay=1 \ --max-retry-delay=20 \ --max-retry-attempts=6 \ --location=us-central1
gcloud beta eventarc enrollments create my-archive-enrollment \ --cel-match="true" \ --destination-pipeline=my-archive-pipeline \ --message-bus=my-message-bus \ --message-bus-project=my-google-cloud-project \ --location=us-central1
別の BigQuery データセットにパイプライン ログを転送します。
これで、Eventarc Advanced バスによって受信されたすべてのメッセージを保存する BigQuery データセットと、パイプライン ログを保存する BigQuery データセットの 2 つの別々のデータセットが作成されます。
失敗したメッセージを特定するには、クエリ ステートメントを使用して、
message_uid
フィールドで両方の BigQuery データセットを結合します。失敗したメッセージを特定したら、Eventarc Publishing API を使用してバスに再度パブリッシュできます。たとえば、Cloud Run サービスまたはジョブをデプロイして、BigQuery からメッセージを読み取り、Eventarc Advanced バスに直接パブリッシュできます。
イベント ハンドラをべき等にする
再試行可能なイベント ハンドラは、次の一般的なガイドラインに沿ってべき等にする必要があります。
- 多くの外部 API では、べき等のキーをパラメータとして指定できます。このような API を使用している場合は、イベントソースと ID をべき等のキーとして使用します。(プロデューサーは、source + id が個別のイベントごとに一意であることを確認する必要があります)。
- また、CloudEvents 属性
xgooglemessageuid
を使用してべき等性を提供することもできます。この属性の値は、Eventarc Advanced メッセージのmessage_uid
フィールドと同じです。イベントの公開アクションを一意に識別します。たとえば、同じイベントがバスに 2 回公開された場合、イベント ハンドラに送信される各イベントには異なるxgooglemessageuid
値が割り当てられます。 - べき等では再試行が安全に行われるため、at-least-once 配信でうまく機能します。したがって、信頼性の高いコードを書くための一般的なベスト プラクティスは、べき等と再試行を組み合わせることです。
- コードが内部でべき等であることを確認します。次に例を示します。
- 結果が変わらずにミューテーションが 2 回以上起こることを確認する。
- 状態を変更する前にトランザクション内のデータベース状態を照会する。
- すべての副作用がそれ自体べき等であることを確認する。
- コードとは関係なく、トランザクション チェックをサービスの外側に置きます。たとえば、指定されたイベント ID がすでに処理されたことを記録している場所の状態を保持します。
- 重複した呼び出しを帯域外で処理するたとえば、重複した呼び出しの後にクリーンアップする別のクリーンアップ プロセスを用意します。