メッセージキューとは? サービス間で作業をバッファリングする
メッセージキューは、プロデューサーとコンシューマーの間でメッセージを保持するバッファであり、それぞれが自分のペースで作業できるようにします。
メッセージキューは、作業を生み出すものと、それを実行するものを疎結合にします。プロデューサーはメッセージを投入し、コンシューマーは準備ができたときにそれを取り出します。コンシューマーが遅れても、キューはバックログを吸収し、作業を捨てたり下流のサービスを過負荷にしたりしません。非同期システムの最も一般的な構成要素の一つです。
キューの仕組み
プロデューサーがメッセージをエンキューし、コンシューマーがそれをデキューして処理し、確認応答 (ack) します。キューは通常、メッセージが少なくとも一度は配信され、ackされるまで保持されることを保証するため、クラッシュしても作業が静かに失われることはありません。
キューが与えてくれるもの
- バッファリング: スパイクはコンシューマーを圧倒せずに平滑化されます。
- 疎結合: プロデューサーとコンシューマーは独立してスケールします。
- リトライ: 失敗したメッセージは再配信できます。
- 耐久性: メッセージはコンシューマーのリスタートを生き延びます。
設計すべき配信保証
ほとんどのキューはat-least-onceであり、メッセージが二度届きうることを意味します。コンシューマーは冪等でなければならず、同じメッセージを再処理しても害がないようにする必要があります。失敗し続けるメッセージは通常、調査のためにdead-letter queueに送られます。
キューに支えられたコードのテスト
CIでは、キューのロジックはしばしば二通りでテストされます。フェイクやインメモリのキューを使ったユニットテストと、service containerとして動く実際のキューに対する統合テストです。シリアライズ、順序付け、確認応答のバグを捕まえるのは統合レイヤーです。
キューはデプロイの安全性を変える
メッセージがキューに残っている間にコンシューマーを再デプロイできるため、処理中の作業を捨てずにデプロイできます。ただしメッセージフォーマットの変更は後方互換を保たねばならず、さもないと新しいプロデューサーが、古いコンシューマーには読めないメッセージをエンキューしてしまいます。
ビルドごとにキューを起動する
実行ごとに実際のブローカーを起動する統合テストは、パイプラインに起動時間を追加します。ウォームなrunner (Latchkeyが提供するようなもの) は、そのオーバーヘッドが素早いフィードバックを支配しないようにします。
重要なポイント
- メッセージキューは作業をバッファリングし、プロデューサーとコンシューマーがそれぞれのペースで動けるようにします。
- at-least-once配信は、コンシューマーが冪等でなければならないことを意味します。
- メッセージフォーマットは契約であり、デプロイをまたいで後方互換を保たなければなりません。