Pub/Sub
Publish/Subscribe
メッセージの送信側(Publisher)が特定の受信者を指定せず、トピックと呼ばれる仲介役を経由して、情報を必要とする受信側(Subscriber)に一斉配信する非同期通信モデル。システム間の結合度を下げ、柔軟な拡張を可能にするアーキテクチャです。
🐾 猫で例えると?
ソファーでくつろいでいる2匹が、飼い主の「おやつ」という声や袋の音(イベント)に対して、同時にクルッと振り向いた瞬間です。音を出した側は「特定の誰か」を指定したわけではありませんが、その情報に興味がある(購読している)複数の猫たちが、それぞれのタイミングで一斉に反応する様子は、まさにPub/Subモデルの動きそのものです。
🐾 猫あるある:IT現場の日常
- 「おなかすいた」という鳴き声:特定の相手を指定せず、トピックに対してイベントメッセージを送信(パブリッシュ)。
- 「おやつ」の音に一斉に振り向く:メッセージを購読している複数のコンシューマーが、並行して非同期に処理を開始。
- 雷の音を聞いてソファー下に潜伏:システム全体へ配信された警告に対し、特定のモジュールが自動でフェイルセーフを実行。
💻 アプリ・Web開発における「Pub/Sub」とは?
従来のシステム連携では、システムAがシステムBのAPIを直接叩く「密結合」な設計が主流でした。しかしこれでは、システムBがダウンするとシステムAまでエラーになったり、新しくシステムCを追加する際にAのコードを書き換える必要が生じます。
そこでPub/Subモデルを導入し、間に「メッセージブローカー(イベントバス)」を挟みます。送信側(Pub)は「ユーザーが登録された」という事実だけをブローカーに投げ、受信側(Sub)は「ユーザー登録トピック」を監視しておきます。これにより、送信側は誰が受信しているかを全く気にすることなく(疎結合)、後からメール送信機能やポイント付与機能(新しいSub)を無傷で追加できるようになります。
⚠️ Pub/Subの仕組みと注意点
Pub/Subの最大のメリットは「システムの拡張性の高さ」と「耐障害性の向上」です。一方で、処理が非同期で行われるため「どの処理がどこまで進んでいるか」を追跡(トレーサビリティ)するのが非常に難しくなります。また、ネットワークの遅延等によりメッセージの到達順序が保証されないケースもあるため、順序に依存する処理には不向きです。
💡 イベント駆動アーキテクチャの基本
Node.jsのEventEmitterを使った、非常にシンプルなPub/Sub概念のコード例です。
// Node.jsでのシンプルなPub/Subの概念例
const EventEmitter = require('events');
const eventBus = new EventEmitter();
// サブスクライバー(受信側)の登録:トピックを購読
eventBus.on('user_registered', (data) => {
console.log(`[メール送信] ${data.name}さんへ歓迎メールを送信`);
});
eventBus.on('user_registered', (data) => {
console.log(`[ポイント付与] ${data.name}さんに初回ポイントを付与`);
});
// パブリッシャー(送信側)がイベントを発火
// 受信側が誰か、何個あるかは気にせず通知を投げるだけ
console.log('ユーザーが新規登録されました。');
eventBus.emit('user_registered', { name: 'Alice' }); 実際の開発現場では、GCPのCloud Pub/SubやAWSのSNS/SQS、Apache Kafka、Redisなどの専用ミドルウェアを使用して、大規模な分散システム間でこのメッセージングを行います。
🛠️ Pub/Subを賢く使うためのポイント
分散システムでPub/Subを導入する際に、現場で必ず考慮すべきベストプラクティスです。
- 冪等(べきとう)性の担保: ネットワークの再送制御により、同じメッセージが2回届く可能性があります。複数回処理しても結果が変わらない(冪等である)ようにSub側を設計する必要があります。
- デッドレターキュー(DLQ)の用意: メッセージの処理に何度も失敗した場合、そのまま破棄するのではなく、原因調査のために専用のキュー(DLQ)に退避させる仕組みが必須です。
- 処理の監視とアラート: メッセージが大量に飛んできてSub側の処理が追いつかず、キューが溜まり続けていないかを監視(メトリクス収集)し、しきい値を超えたらアラートを鳴らします。
飼い主が「おやつ(Pub)」というイベントを発火させた時、アメショは凄まじい圧で迫り、茶トラはゴロンゴロンとお腹を見せてアピールします。同じメッセージを受け取っても、それぞれのシステム(猫)が完全に独立して異なる処理(Sub)を実行できるのが、Pub/Subの面白くて強力なところですね。