Pub/Sub
発行者と購読者が直接通信せず、メッセージブローカーを介して非同期にメッセージを交換するパターン
Pub/Sub とは
Pub/Sub (Publish/Subscribe) は、メッセージの発行者 (Publisher) と購読者 (Subscriber) が直接通信せず、トピックやチャネルを介して非同期にメッセージを交換するパターンである。発行者は「誰が購読しているか」を知らず、購読者は「誰が発行したか」を知らない。この疎結合性がマイクロサービス間の連携に適している。
Observer パターンと似ているが、Pub/Sub はメッセージブローカーが仲介する点が異なる。Observer はオブジェクト間の直接的な通知であり、プロセス内で完結する。Pub/Sub はプロセスやサービスの境界を越えて機能する。
ポイントツーポイントとの違い
両者の分かれ目は「1 つのメッセージを何人が受け取るか」にある。Pub/Sub では購読者全員が同じメッセージのコピーを受け取り、ポイントツーポイントでは 1 つのコンシューマーが取り出した時点で他からは見えなくなる。
| 観点 | Pub/Sub | ポイントツーポイント (キュー) |
|---|---|---|
| 配信先 | 全購読者に配信 (ファンアウト) | 1 つのコンシューマーだけが処理 |
| 用途 | イベント通知、データ同期 | タスクの分散処理、ワークキュー |
| メッセージの消費 | 各購読者が独立して消費 | 1 つ消費されたら消える |
| AWS サービス | SNS, EventBridge | SQS |
| 例 | 「注文が作成された」を通知 → 在庫、決済、通知が各自処理 | 「画像をリサイズせよ」→ 1 つのワーカーが処理 |
実務では両方を組み合わせる。SNS (Pub/Sub) で複数の SQS キュー (ポイントツーポイント) にファンアウトし、各キューのコンシューマーが独立して処理する「SNS + SQS ファンアウト」パターンが定番だ。
AWS での実装パターン
SNS + SQS ファンアウト
最も一般的な Pub/Sub パターン。SNS トピックに発行し、複数の SQS キューが購読する。
注文サービス → SNS (OrderCreated)
├→ SQS (在庫キュー) → Lambda (在庫引当)
├→ SQS (決済キュー) → Lambda (決済処理)
└→ SQS (通知キュー) → Lambda (メール送信)
SQS を挟むことで、各購読者が独立してリトライ・スケーリングできる。SNS から Lambda を直接呼び出すこともできるが、SQS を挟む方がエラーハンドリングが柔軟だ (DLQ、可視性タイムアウト、バッチ処理)。
EventBridge
EventBridge はルールベースのフィルタリングで、条件に合致するターゲットにのみイベントを配信する。ただし「絞り込みができるのは EventBridge だけ」ではない。SNS も購読 (サブスクリプション) ごとにフィルターポリシーを設定でき、既定では全購読者が全メッセージを受け取る一方、ポリシーを付けた購読者は条件に合うメッセージだけを受け取る (Amazon SNS 開発者ガイド)。両者の差は絞り込みの宣言場所で、SNS は購読側に条件を持たせ、EventBridge はルール側にイベントパターンを持たせて 1 つのルールから Lambda・Step Functions・SQS といった異種のターゲットへ振り分ける。
{
"source": ["order-service"],
"detail-type": ["OrderCreated"],
"detail": {
"total": [{ "numeric": [">=", 10000] }]
}
}
この例では、1 万円以上の注文だけを特定の Lambda に配信する。
メッセージの順序保証
標準の SNS/SQS は順序を保証しない。順序が重要な場合の選択肢は以下のとおり。
| サービス | 順序保証 | スループット | 用途 |
|---|---|---|---|
| SNS + SQS (Standard) | なし | 発行はアカウント + リージョン単位のクォータ内 (東京リージョンの既定は 1,500 メッセージ/秒) | 順序不問のイベント通知 |
| SNS FIFO + SQS FIFO | あり (メッセージグループ単位) | メッセージグループあたり 300 メッセージ/秒 (トピック単位に切り替えた場合の既定は 3,000 メッセージ/秒または 20 MB/秒) | 順序が重要な処理 |
| Kinesis Data Streams | あり (シャード単位) | シャードあたり 1,000 レコード/秒かつ 1 MB/秒 (書き込み) | 高スループットのストリーム処理 |
数値は 2026 年 8 月時点の既定クォータで、引き上げ申請や高スループット FIFO の有効化で変わる。標準構成にも発行側のリージョン上限があるため、上限なしと考えないことが要点だ。また FIFO 経路は SNS 側と SQS 側の両方で制限を受ける。SQS の FIFO キューは、バッチ処理なしなら送信・受信・削除の各操作が 300 メッセージ/秒、バッチ処理ありなら 3,000 メッセージ/秒が既定であり、実効スループットは経路上の最も低い上限に張り付く。
よくある失敗パターン
購読者の障害の閉じ込め方を誤る
SNS から Lambda を直接呼び出す構成で Lambda がエラーを返すと、SNS はその購読の配信ポリシーに従ってリトライする。ここで誤解しやすいのは、リトライが他の購読者への配信を止めるわけではない点だ。配信もリトライも購読ごとに独立している。実害は別の形で出る。第 1 に、配信ポリシーを使い切ると SNS はリトライを止めてメッセージを破棄する。購読にデッドレターキューを付けていなければ、そのイベントは痕跡なく失われる。第 2 に、Lambda の同時実行数は既定でアカウントとリージョンあたり 1,000 という共有の枠であり、失敗した呼び出しの再試行が積み上がると同じリージョンの他の関数が枠を食われてスロットリングされる。SQS を挟めば、未処理のメッセージはキューに残り、リトライ回数と可視性タイムアウトを購読者側で制御できるため、障害の影響がその経路に閉じる。
メッセージの重複処理
Pub/Sub は「少なくとも 1 回配信 (at-least-once)」が基本だ。ネットワーク障害やリトライにより、同じメッセージが複数回配信される可能性がある。購読者側でべき等性を確保する設計が必須だ。
体系的に学ぶなら関連書籍を参照してほしい。
この記事は役に立ちましたか?
関連用語
イベント駆動アーキテクチャ
イベントの発行と購読を中心にシステムを構成し、サービス間の疎結合と非同期処理を実現するアーキテクチャスタイル
ファンアウト
1 つのイベントを複数のコンシューマーに同時配信するメッセージングパターン
SNS と SQS
AWS のメッセージングサービスで、SNS がパブリッシュ/サブスクライブ、SQS がメッセージキューを提供する
SNS ファンアウト
SNS トピックから複数の SQS キューや Lambda に同時配信し、1 つのイベントで複数の処理を並行実行するパターン
メッセージキュー
プロデューサーとコンシューマーを非同期に接続し、メッセージを一時的に保持する通信基盤
デッドレターキュー
処理に失敗したメッセージを退避させ、後から調査 / 再処理するためのキュー