[メッセージミドルウェア] RocketMQ メッセージの繰り返し消費シナリオとソリューション

序文

メッセージの繰り返しの消費は、すべての MQ で発生する一般的な問題の 1 つであり、一部の機密性の高いシナリオでは、メッセージの繰り返しの消費は、繰り返しの控除などの深刻な結果を引き起こす可能性があります。

それでは、RocketMQ によるメッセージの繰り返し消費はどのような状況で発生するのでしょうか?

  1. システムの呼び出しリンクが比較的長い場合、たとえば、システム A がシステム B を呼び出し、システム B が RocketMQ にメッセージを送信します。結果がシステム A に返されると、システム A はリクエストを再開始しようとします。システム B が繰り返し処理し、RocketMQ への複数のメッセージを開始し、繰り返し消費されることになります。
  2. システム B が RocketMQ にメッセージを送信するときにも、上記と同じ問題が発生する可能性があり、メッセージの送信がタイムアウトになり、その結果システム B が再試行し、RocketMQ が重複したメッセージを受信することになります。
  3. RocketMQ がメッセージを正常に受信し、処理のためにコンシューマに引き渡したとき、コンシューマが消費の完了後にオフセットを RocketMQ に送信する時間がなく、コンシューマがクラッシュするか自身を再起動した場合、RocketMQ は消費があったとみなします。オフセットを受信しない場合は失敗し、再度消費するためにメッセージをコンシューマに再送信します。

ここに画像の説明を挿入

メッセージの繰り返し消費のシナリオは、プロデューサー側での繰り返し消費とコンシューマー側での繰り返し消費に大別できますが、メッセージの繰り返し消費をどのように解決すればよいでしょうか。

答えはべき等性によって保証されており、メッセージの繰り返しの消費が結果に影響を与えない限り、この問題は完全に解決できます。

  • プロデューサー側で冪等性を確保したい場合は、おそらく次の 2 つの方法を使用できます。

    1. RocketMQ はメッセージ クエリの機能をサポートしています。RocketMQ にアクセスしてメッセージが送信されたかどうかを確認し、メッセージが存在しない場合は送信し、存在する場合は送信しません。
    2. redis を導入します。RocketMQ へのメッセージの送信が成功したら、redis にデータを挿入します。再試行が発生した場合は、まず redis にアクセスしてメッセージが送信されたかどうかを確認します。存在する場合、メッセージは繰り返し送信されません。
  • プロデューサーの 2 つの冪等スキームは実現できますが、特定の欠陥があります。

    • 解決策①、RocketMQ メッセージ クエリのパフォーマンスはあまり良くありません。同時実行性が高いシナリオでは、各メッセージが RocketMQ に送信されるときにクエリされるため、インターフェイスのパフォーマンスに影響を与える可能性があります。
    • 解決策②、いくつかの極端なシナリオでは、メッセージが正常に送信された後、redis は redis に正常に書き込むことができることを保証できません。たとえば、メッセージが正常に書き込まれ、現時点で redis がダウンしている場合は、redis を再度クエリします。メッセージが送信されたかどうかを判断するため、正しい結果を得ることができません

プロデューサー側で冪等な解決策を実行するのはあまり信頼できないため、コンシューマ側で実行しましょう

  • メッセージの消費は、最終的にはデータベースの操作に対応します。メッセージを消費するときに、メッセージがデータベースで消費されたかどうかを判断する限り、冪等性を保証できます。たとえば、一意のインデックスを使用して、冪等性を保証できます。メッセージは 1 回だけ消費されます。
    ここに画像の説明を挿入

  • メッセージの繰り返しの消費は、非常に一般的な問題です。システム コールが頻繁に行われる多くのシナリオでは、タイムアウトの再試行が発生する可能性があります。さらに、システムが頻繁に反復され、更新のためにシステムが頻繁に再起動されるシナリオでも、メッセージの繰り返しの消費が発生する可能性があります。

  • 実際には、プロデューサが RocketMQ に繰り返しメッセージを送信することは大きな問題ではありません。メッセージは RocketMQ 内で繰り返されるだけであり、システムのデータには影響しません。最後にデータベースを変更するときに冪等性を確保する必要があるだけです。

おすすめ

転載: blog.csdn.net/u011397981/article/details/130681291