非同期処理(キュー・ジョブ)— 重い仕事は後回しにする

概要 — まず全体をつかむ

初級では非同期処理を「番号札」と捉えました。中級では、メッセージング(producer/broker/consumer)と配信保証を見ます。

詳細 — 1段階ずつ追う

これは何をする係?

非同期は「送る側・仲介・受ける側」の3者で成り立ちます。

  • プロデューサ — 仕事(メッセージ)を積む側
  • ブローカー — キューを預かる仲介(RabbitMQ・SQS・Kafka など)
  • コンシューマ(ワーカー) — 取り出して処理する側

登場人物メモ:

  • ※1 ack(確認応答) — 「処理し終えた」をブローカーに返す。ackするまで消えない
  • ※2 冪等性 — 同じメッセージを複数回処理しても結果が同じ
この部分をもっと深く(上級
  • キュー型(RabbitMQ・SQS)— 取り出したら消える。ワーカーで分担
  • ログ型(Kafka)— 追記されたログを各コンシューマが自分のオフセットで読む。再処理しやすい
  • パーティション — 並列度の単位。同一パーティション内でのみ順序保証
やさしく言うと(初級

人気店で「お先にどうぞ、出来たら番号でお呼びします」と番号札をもらう——あの仕組みです。重い依頼はキュー(※1 待ち行列) に積み、ワーカー(※2) が順にこなします。

登場人物メモ:

  • ※1 キュー — 仕事を順番に並べる待ち行列
  • ※2 ワーカー — キューから仕事を取り出して処理する係
  • ※3 ジョブ — 1件の仕事(例:この動画を変換する)

仕事の流れ

  1. プロデューサがメッセージを enqueue(積む)
  2. ブローカーがキューで保持
  3. ワーカーが dequeue して処理
  4. 成功したら ack。失敗なら再配信(リトライ)
  5. 何度も失敗するものは デッドレターキュー へ退避
アニメーション『メッセージキュー』を開く
メッセージキュー📤 送り手プロデューサ積むだけで即解放enqueue(積む)キュー(順に並ぶ箱の列)古い ←→ 新しいdequeue🛠 ワーカー1自分のペースで取り出す🛠 ワーカー2自分のペースで取り出す🛠 ワーカー3自分のペースで取り出す何度も失敗したものだけ⚠️ デッドレターキュー(DLQ)あとで調べるため退避(詰まりを防ぐ)送り手と受け手を切り離し、混んでも取りこぼさない

1件の仕事が「投入 → 取り出し → 実行 → 完了通知(ack)」をたどる流れは、次のアニメで1手ずつ追えます。

アニメーション『非同期処理(キュー→ワーカー)』を開く
プロデューサキューワーカー
  • プロデューサ仕事(メッセージ)を積む側。積んだら即解放され、処理の完了は待たない
  • キュー仕事を順に預かる箱の列。ackされるまでメッセージを消さずに保持する
  • ワーカー取り出して実処理する側。自分のペースで進め、混雑時は台数を増やせる
送る側と受ける側を切り離すのが要点です。仕事が混んできたらワーカーを増やせば、同じキューから並列で捌けます。「▶ 再生」か「次へ」でどうぞ。
0 / 4
この部分をもっと深く(上級
  1. プロデューサが永続化+レプリカされたブローカーへ送る
  2. コンシューマグループが分担して読む(各パーティション1消費者)
  3. 処理後にack/オフセットコミット
  4. 失敗は再配信、繰り返す失敗はDLQへ
やさしく言うと(初級
  1. 重い依頼が来る(例:動画をアップロードした)
  2. その仕事をジョブとしてキューに積む
  3. 利用者にはすぐ「受け付けました」を返す(待たせない)
  4. 裏でワーカーがキューから順に取り出して処理する
  5. 終わったら通知する(メール・画面更新など)

設計の勘所

  • 配信保証 — at-least-once(重複しうる)/at-most-once(取りこぼしうる)。多くはat-least-once+冪等
  • 順序 — 厳密な順序保証はコストが高い。必要な範囲だけに絞る
  • スケール — ワーカーを増やして並列処理(水平スケール)
  • 優先度・遅延 — 緊急ジョブを先に、指定時刻に実行、なども
  • 可視性タイムアウト(visibility timeout) — 取り出したメッセージは一時的に他ワーカーから隠れ、ack前に時間切れになると再出現する(重複配信の実際の発生源)
この部分をもっと深く(上級
  • exactly-onceの実像 — at-least-once+冪等、またはトランザクショナルな読み書き
  • トランザクショナルoutbox — DB更新とイベント発行を取りこぼさず一致
  • スキーマレジストリ — メッセージ形式の進化を管理(後方互換)
  • 順序と並列 — 順序を厳しくすると並列度が下がる。キー設計で両立を探る
やさしく言うと(初級
  • 待たせない — 重い処理を待たずに、すぐ画面を返せる
  • 混雑をならす — 一度に殺到しても、キューに溜めて順にさばける
  • 失敗に強い — うまくいかなかったジョブを、あとで再試行できる

メール送信・画像/動画の変換・大量集計・通知などが定番の使いどころです。

⚠️ うまくいかないとき

  • 重複配信 — at-least-onceゆえ。冪等にして二重実行を無害化する
  • 順序の乱れ — 並列処理で前後する
  • バックプレッシャ(詰まり) — 積む速度>処理速度で溜まり続ける
  • ポイズンメッセージ — 壊れたジョブが無限リトライ。DLQで隔離する
この部分をもっと深く(上級
  • リバランスの停止 — コンシューマ増減時に一時停止・重複
  • オフセットのずれ — コミット漏れで重複、先行コミットで欠落
  • ホットパーティション — 特定キーに集中して詰まる
  • ポイズンメッセージ — 壊れたメッセージが再処理を止める(DLQ)
やさしく言うと(初級
  • 処理が詰まる — 積まれる量にワーカーが追いつかず、完了が遅れる
  • 二重実行 — 同じジョブが2回動いてしまう(メールが2通、など)
  • 失敗の放置 — エラーになったジョブに気づけない

理解度チェック

そのまま解けます(成績は保存されません)。無料アカウントを作ると、学習の記録と進捗の山登りが始まります。

1. 「メッセージは最低1回は届く(重複はありうる)」という配信保証はどれ?

2. 「処理し終えた」をブローカーに返す確認応答を、英字3文字で答えてください。

3. プロデューサがメッセージをキューに積む操作を、英語1語で何と言いますか。

4. 何度リトライしても失敗し続けるジョブを、隔離して溜めておく先を何と呼ぶ?

5. 取り出したメッセージが一時的に他ワーカーから隠れ、ack前に時間切れになると再び現れる仕組みは?

6. メッセージを積む速度が処理する速度を上回り、キューに溜まり続ける状態を何と呼ぶ?

7. at-least-onceによる重複配信に備えて、コンシューマ側に持たせるべき性質はどれ?

8. プロデューサ・ブローカー・コンシューマの役割分担として正しいのは?