Dev Study
AWSサービスの内部原理 コース

21. 呼び出しの3経路(1) 同期と非同期 — 内部キューとリトライの仕組み

Lambdaの呼び出しは「応答を待つ同期」と「待たない非同期」に分かれ、非同期ではキュー・リトライ・DLQ・宛先という仕組み一式がエラー処理の責任を肩代わりします — その内部を図で追っていきましょう。

① 分岐点は「応答を待つか、待たないか」

同期呼び出しInvocationType=RequestResponse
非同期呼び出しInvocationType=Event
応答
完了まで待つコネクション保持 → 結果を受け取る
202 を即返す関数はまだ動いてすらいない
エラーの後始末
呼び出し元の責任エラーを読み、必要なら呼び直す
Lambdaは応答を返して終わり
Lambdaが肩代わりキュー・リトライ・DLQ・宛先
呼び出し元はもう待たない
  • 「後始末を誰がやるか」の一点が、2つの経路の設計をまるごと分ける

同期は完了まで待って結果を受け取るため、エラーの後始末は呼び出し元の責任。非同期は202が即返り、後始末はLambda側の仕組みが引き取る。

② 非同期の正体 — 内部キューで切り離す

あなたプロデューサ
イベント送信 → 202「積めました」
内部メッセージキュー受け取ったイベントをまず置く
1件ずつ取り出す
ワーカー(別プロセス)コンシューマ
渡す
関数の実行
  • 切り離されているから、呼び出し元は待たずに帰れる
  • 実行側は自分のペースで、リトライも含めて処理できる

202は「キューに積めました」であって「実行しました」ではない。プロデューサとコンシューマをキューで切り離す、メッセージキューによる非同期処理そのもの。

③ 自動リトライ — エラーの種類で2つの流儀

関数がエラーを返すコード内の例外・ランタイムのタイムアウト
スロットリング / システムエラー429(同時実行数不足)・500系
リトライのやり方
さらに2回まで再実行1回目→2回目: 1分待ち / 2回目→3回目: 2分待ち
キューに戻して再試行デフォルトで最大6時間
計3回で終わり
指数バックオフ1秒から指数関数的に増加、最大5分で頭打ち
  • キューが長く詰まると、Lambda自身も再試行間隔を広げてキューを読む速度を落とし、系全体が落ち着くのを待つ

関数自身のエラーは間隔を固定して最大2回の再実行。スロットリングやシステムエラーはキューに戻し、指数バックオフで最大6時間粘る。

④ at-least-once の帰結 — 関数は冪等に書く

内部キュー結果整合(eventually consistent)
同じイベントが複数回届くことがある
関数エラーを返していなくても重複配送はありえる
だから
コードを冪等(idempotent)に同じイベントを2回受け取っても結果が壊れない
  • 配送は「少なくとも1回」であって「ちょうど1回」ではない
  • ちょうど1回を保証しないのは怠慢ではなく、キューを使った疎結合設計の必然的な代償

内部キューは結果整合なので、エラーがなくても同じイベントが複数回届きうる。だから非同期で呼ばれる関数は冪等に書く必要がある。

⑤ 処理しきれなかったイベントの受け皿 — DLQと宛先

全リトライを使い果たした
有効期限切れ最大イベント経過時間を超過(キューの長い詰まりで発生)
そのままなら破棄 — 失敗が見えなくなる
DLQ(デッドレターキュー)破棄されるイベントを捕まえる
on-failure 宛先タイムアウト・ランタイムエラー等の失敗記録
on-success 宛先成功の記録も送れる
下流へ
SQS / EventBridge切り離した結果を別コンポーネントへつなぐ起点
  • 同期では呼び出し元が握っていたエラー処理の責任を、非同期ではキュー・リトライ・DLQ・宛先の一式が肩代わりする — これが2経路の本質的な違い

期限切れやリトライ使い果たしで破棄されるイベントはDLQで捕まえる。失敗・成功の記録は宛先(destinations)から下流へつなげる。

公式ドキュメントで詳しく ↗