メッセージの冪等性とは
メッセージキューでは、ネットワークの例外やシステム障害が原因で、メッセージがコンシューマーに繰り返し配信される場合があります。この場合、メッセージに対して冪等処理を実行することで、ビジネスロジックが1回だけ実行されるようにすることができます。これにより、メッセージの重複消費によって発生するデータエラーや結果の不整合を最小限に抑えることができます。
たとえば、コンシューマーは、支払控除メッセージに基づいて注文の支払いを控除します。支払額は 100 米ドルです。ネットワークの例外またはシステム障害が原因で、メッセージがコンシューマーに繰り返し配信されます。その結果、メッセージが繰り返し消費されます。ただし、支払いは1回だけ控除され、注文に対して 100 米ドルの控除レコードが1つだけ作成されます。この例では、メッセージ消費プロセスでメッセージの冪等性が実装され、支払控除はビジネス要件を満たしています。
シナリオ
システムがネットワークのジッター、システム障害、メッセージの重複、その他の異常などに遭遇した場合、特に分散システムでは、メッセージが繰り返し消費される可能性があります。この場合、メッセージの冪等性を使用して、システムの信頼性と整合性を向上させることができます。同じメッセージが繰り返し消費される可能性のある原因は次のとおりです。
メッセージの消費時間が非表示期間を超えている: コンシューマー A がメッセージを処理するのにかかる時間が、メッセージの InvisibleDuration パラメーターの値よりも長い場合、メッセージはコンシューマー B に再配信され、コンシューマー A と B の両方で同じメッセージが処理されます。
ネットワークの例外またはジッター: メッセージがコンシューマーによって正常に処理された後、ネットワークが切断されます。この場合、リクエストDeleteMessage
は応答せず、ネットワークが回復した後にメッセージがコンシューマーに再配信されます。
ブローカーまたはサービスコンシューマーの再起動: メッセージがコンシューマーによって正常に処理された後、ブローカーまたはサービスコンシューマーを再起動すると、システムがDeleteMessage
リクエストに応答できない場合があります。この場合、非表示期間が経過した後にメッセージがコンシューマーに再配信される可能性があります。
処理方法
メッセージキューでは、通常、メッセージIDがメッセージに対して冪等処理を実行するための冪等キーとして使用されます。ただし、メッセージIDが異なるメッセージに同じ内容が含まれている場合があります。競合や重複を避けるために、メッセージIDに基づいてメッセージに対して冪等処理を実装しないでください。ビジネスを一意に識別する識別子を冪等キーとして設定することをお勧めします。
一意の識別子: 各メッセージに一意の識別子を割り当てます。メッセージがコンシューマーに配信されると、メッセージの一意の識別子が記録されます。これにより、このコンシューマーによってメッセージが再度消費されないようになります。
データベース制約: データベースに一意制約を設定します。制約違反のために保存されたデータは挿入できないため、冪等性が実現します。
ビジネス状態の定期的なチェック: コンシューマーは、メッセージの現在の状態をチェックする前にメッセージを消費することはできません。たとえば、コンシューマーは、メッセージが存在するかどうか、または処理済みかどうかを確認する必要があります。存在する場合、または処理済みの場合、後続の操作を実行せずにメッセージが直接返されます。
マージ操作: 冪等性を実現するために、特定の操作のためにいくつかのメッセージをマージできます。このようにして、最終的な消費結果は最初の消費結果と同じになります。