RabbitMQを使用する際、一部のビジネスシナリオでは順次消費を保証する必要があります。例えば、データの追加、変更、削除操作を行う3つのメッセージが生成されるビジネスシナリオでは、消費の順序が保証されないと、実行順序が削除、変更、追加となり、乱れが生じる可能性があります。
以下に示すように:
RabbitMQにおけるメッセージ順序の問題は、メッセージの送信順序、キュー内のメッセージの順序、メッセージの消費順序の3つの側面で考慮する必要があります。
メッセージの送信順序
メッセージ送信元でのメッセージの送信順序は、ほとんどのビジネスに厳密に必要とされません。誰が最初にメッセージを送信しても問題ありません。メッセージを順次送信する必要がある場合は、グローバルロックを使用して一度に1つのメッセージしか送信できず、並行してメッセージを送信することはできません。
キュー内のメッセージの順序
RabbitMQでは、メッセージは最終的にキューに格納されます。同じキュー内では、メッセージは先入れ先出しの原則に基づいて順序付けられ、これはRabbitMQによって保証されており、通常は開発者が気にする必要はありません。
注: 異なるキュー内のメッセージの順序は保証されません。例えば、地下鉄駅に入る際、3つの列の中から1つを選んだ場合、異なる列間での入場順序は保証されません。
メッセージの消費順序
メッセージの順次消費を確保する方法について議論する際、一般的には消費者がメッセージを消費する順序を指しています。同じメッセージキューから複数の消費者がメッセージを消費するシナリオでは、通常はメッセージの順序付けを保証することはできません。冒頭の図で示されているように、メッセージキュー内のメッセージは順序付けられていても、複数の消費者が同時にメッセージを消費し、メッセージの取得速度、ビジネスロジックの実行速度、および実行時の例外がすべてメッセージの順序を不整合にさせる可能性があります。
例えば: メッセージA、B、Cが順番にキューに入ります。消費者A1がメッセージAを取得し、消費者B1がメッセージBを取得します。しかし、消費者B1の実行が速い場合、消費者A1よりも早く完了するか、消費者A1がエラーに遭遇する場合、どちらのシナリオもメッセージの順序の不整合を引き起こす可能性があります。
順次消費の問題への典型的な解決策は、キューに1つの消費者しかないようにすることです このようにすることで、メッセージを順番に1つずつ処理できます。欠点としては、並行能力が低下し、複数のメッセージを同時に消費することができません。これはトレードオフです。
注: ビジネスが順次消費と並行性の増加を要求する場合、一般的なアプローチは複数のキューを有効にすることです。ビジネスはルールに基づいて異なるキューにメッセージを配布することで、並行性レベルを高めることができます。例えば、電子商取引の注文シナリオでは、同じユーザーの注文メッセージの順序を保証する必要がある場合に適用されます。異なるユーザーに属するメッセージは異なるキューに送られることができます。