0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Azure Functions で検証する Azure Event Grid のリトライ動作

0
Last updated at Posted at 2026-05-17

概要

Azure Event Grid の公式ドキュメントには「30 秒以内にエンドポイントが応答しない場合は再試行キューに入れる」と記載されています。しかし、Azure Functions をエンドポイントとして実際に検証したところ、30 秒を超えてもすぐにはリトライが発生しない動作を確認しました。

# 待機秒数 リトライ発生 Event Grid のステータス
1 5 秒 なし Delivered
2 50 秒 なし Delivered
3 240 秒 あり Delivery Failed

ただしドキュメントには「ベストエフォート方式で再試行キューから削除しようとする」と明記されており、重複配信の可能性も残ります。そのため、本番運用では 30 秒以内に処理を完了させる設計 が安全と考えられます。

ドキュメントが定めるリトライ仕様

Azure Event Grid のリトライ仕様について、公式ドキュメント(Azure Event Grid の配信と再試行の説明)には次の記述があります。

Event Grid は、メッセージの配信後、応答を 30 秒間待機します。30 秒後、エンドポイントが応答しない場合、Event Grid は再試行のためにメッセージをキューに入れます。

image.png

引用元: Azure Event Grid の配信と再試行の説明 - Azure Event Grid | Microsoft Learn

一方で、3 分以内に応答すれば再試行キューから削除されうるという記述もあります。

エンドポイントが 3 分以内に応答した場合、Event Grid はベスト エフォート方式でイベントを再試行キューから削除しようとしますが、それでも重複が受信される可能性があります。

image.png

引用元: Azure Event Grid の配信と再試行の説明 - Azure Event Grid | Microsoft Learn

つまり、「30 秒経過 = 即リトライ確定」ではなく、3 分以内なら取り消される余地がある という、ややグレーな仕様になっています。今回の検証では、この境界の挙動を具体的に確かめました。

検証環境

利用したリソース

リソース 用途
Azure Storage イベント発生源となる Blob ストレージ
Azure Functions Event Grid トリガー関数(エンドポイント)
Azure Event Grid Blob 作成イベントを Functions にルーティング

Azure Functions のコード

WAIT_SECONDS 環境変数で待機時間を変更できる、シンプルな Event Grid トリガー関数を用意します。受信したイベントの内容をログに出力したあと、指定秒数だけ time.sleep して応答を遅延させます。

import json
import logging
import os
import time
from datetime import datetime, timezone

import azure.functions as func


app = func.FunctionApp()


WAIT_SECONDS = os.getenv("WAIT_SECONDS", "50")


@app.function_name(name="BlobCreatedEventGridProbe")
@app.event_grid_trigger(arg_name="event")
def blob_created_event_grid_probe(event: func.EventGridEvent) -> None:
    wait_seconds = int(WAIT_SECONDS)

    event_time = event.event_time
    if event_time is not None and event_time.tzinfo is None:
        event_time = event_time.replace(tzinfo=timezone.utc)
    elif event_time is not None:
        event_time = event_time.astimezone(timezone.utc)

    data = event.get_json()
    blob_url = data.get("url") if isinstance(data, dict) else None

    log_record = {
        "probe": "event-grid-blob-created-latency",
        "utc_now": datetime.now(timezone.utc).isoformat(),
        "event_id": event.id,
        "event_type": event.event_type,
        "event_time": event_time.isoformat() if event_time else None,
        "subject": event.subject,
        "blob_url": blob_url,
        "data": data,
    }

    logging.info(
        "EVENTGRID_PROBE %s",
        json.dumps(log_record, ensure_ascii=False),
    )

    # 指定秒数だけ応答を遅延させる
    logging.info("Waiting for %d seconds before returning response...", wait_seconds)
    time.sleep(wait_seconds)

    logging.info("処理が完了しました。%d 秒待機しました。", wait_seconds)

image.png

Event Grid サブスクリプションの設定

Blob 作成イベントを上記 Functions にルーティングするよう、Event Grid サブスクリプションを構成します。

image.png

image.png

検証ケースとその結果

ケース 1:5 秒待機

WAIT_SECONDS5 に設定して Blob を作成します。短時間で応答が返るため、想定通り Delivered Events として処理されました。

image.png

image.png

image.png

image.png

ケース 2:50 秒待機 — リトライ閾値ちょうど

WAIT_SECONDS50 に設定すると、ドキュメント上の「リトライ閾値」とちょうど同じタイミングで応答することになります。このケースでも結果は Delivered Events で、リトライは発生しませんでした。

つまり、ドキュメントに書かれた「30 秒後にキューに入れる」というのは、ただちにリトライ配信が走ることを意味しないことが確認できます。

image.png

image.png

image.png

image.png

ケース 3:240 秒待機 — 3 分の壁を超える

WAIT_SECONDS240(= 4 分)に設定すると、Delivery Failed Events に分類され、リトライが発動しました。

ここで注目すべきは、Azure Functions 側では関数が正常終了している点です。それにもかかわらず Event Grid 側からは失敗扱いとなり、ドキュメント記載のリトライスケジュールに従って再配信が繰り返される結果となりました。

image.png

image.png

image.png

image.png

image.png

リトライスケジュールはドキュメントにも明記されており、何度も処理が走る点に注意が必要です。

image.png

image.png

image.png

引用元: Azure Event Grid の配信と再試行の説明 - Azure Event Grid | Microsoft Learn

検証から得られる設計上の示唆

今回の検証結果は、Event Grid を組み込んだシステムを設計するうえで以下を意味します。

  1. 「30 秒」はキュー投入の閾値であって、即時リトライの閾値ではない
    ドキュメント上の 30 秒は、あくまで Event Grid 内部で再試行キューに入れるタイミング。3 分以内に応答すれば、ベストエフォートではあるものの再配信を回避できる可能性があります。
  2. 3 分を超える処理は重複配信が確定的に発生する
    240 秒のケースのように、関数自体が正常終了していても Event Grid から見れば失敗扱いとなり、リトライがスケジュールされてしまいます。長時間処理をそのままトリガー関数に書くと、冪等性のない処理が複数回走る リスクがあります。
  3. 本番では「30 秒以内に応答を返す設計」を基本とする
    重複配信を確実に避けたいのであれば、ドキュメントの定める 30 秒以内で処理を完了させるのが安全。それが難しい場合は、トリガー関数では受信確認だけを行い、実処理を Queue Storage や Service Bus にオフロードするパターンが有効です。また、下流側で冪等性を担保しておくと、ベストエフォートで取り消し切れなかった重複にも耐えられます。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?