RocketMQ ソース コード分析 - 分散トランザクション ソリューション

メッセージキューはトランザクションの問題を解決します

トランザクションを解決するためにメッセージ キューが使用される場合、メッセージはどの段階で MQ に送信されますか?

  1. 金額を差し引いてから
    RocketMQ にメッセージを送信 金額を差し引いてからメッセージを送信 メッセージの送信がタイムアウトすると(MQ では成功する場合と失敗する場合があります)、状態の判断が難しくなります。

  2. 最初に RocketMQ にメッセージを送信してから
    お金を差し引きます。引き落とし成功メッセージは正常に送信されますが、ローカルの差し引きビジネスが失敗した場合、メッセージは MQ に送信され、お金を追加する 2 番目のフェーズが正常に実行されます。

したがって、どのソリューションを採用しても、その処理には問題が発生します。

実際、注意深く分析した結果、この問題の重要な点は、RocketMQ がメッセージ送信者のトランザクション ステータスを変更できないことです。したがって、RocketMQ の分散トランザクション ソリューションは最適化されています。

RocketMQ の分散トランザクション ソリューション

画像.png

RocketMQ は、分散トランザクションにセミトランザクションおよびトランザクション レビュー メカニズムを導入します。

セミトランザクション:
メッセージを rocketmq に送信します。ただし、メッセージは commitlog に保存されるだけで、consumeQueue には表示されません。つまり、コンシューマー (サブスクライバー) はメッセージを表示できません。

取引レビュー:

RocketMq はコミットログ内のセミトランザクション メッセージを定期的に走査します。このトランザクション レビュー メカニズムは、RocketMQ の観点からメッセージ送信者のトランザクションに参加できます。

RocketMQ 分散トランザクションのケース コード

画像.png

これは分散トランザクションのプロデューサーであり、半分のトランザクションの送信を完了します。

TransactionListenerImpl クラスの useLocalTransaction メソッドでトランザクション レビューを行うと、ローカル トランザクションが正常に実行されると、commit_message が送信され、コンシューマーはメッセージを消費できます。

画像.png

このステップで確認できない、時間のかかる操作がある場合は、「不明」を送信して、スケジュールされたタスクのレビューに処理を任せることができます。

画像.png

画像.png

分散トランザクションのソースコード解析

分散トランザクションのプロセスは、メッセージ送信、確認/ロールバック、レビューの3つの側面から分析できます。

画像.png

メッセージ送信ソースコード解析

プロデューサー

画像.png

画像.png

画像.png

ブローカ

RocketMQ は Netty を使用してネットワークを処理し、ブローカーがメッセージの書き込みリクエストを受信すると、SendMessageProcessor クラスの processRequest メソッドに入ります。

最後に、DefaultMessageStore クラスに asyncPutMessage メソッドを入力してメッセージを保存します。

画像.png

画像.png

画像.png

図とコードを組み合わせると、トランザクション メッセージが送信されるとき、メッセージが実際に保存されるトピックはシステム トピックであることがわかります: RMQ_SYS_TRANS_HALF_TOPIC

同時に、メッセージには、メッセージの元のトピックに関連する情報とキューが保存されます。

画像.png

ソースコード解析の確認/ロールバック

プロデューサー

DefaultMQProducerImpl クラスの sendMessageInTransaction メソッド

画像.png

画像.png

画像.png

ブローカ

画像.png

EndTransactionProcessor クラス

画像.png

画像.png

画像.png

ソースコード分析のバックチェック

プロデューサー

トランザクションのレビュー中、プロデューサーはサーバーとなるため、サービス処理のために登録する必要があります。

画像.png

画像.png

DefaultMQProducerImpl クラスの checkTransactionState メソッド

画像.png

画像.png

DefaultMQProducerImpl クラスの processTransactionState メソッド

画像.png

画像.png

画像.png

画像.png

ブローカ

ブローカーが開始されると、クライアントとして機能し、トランザクションのレビューのために定期的にクライアントにアクセスします。

画像.png

画像.png

画像.png

画像.png

画像.png

画像.png

画像.png

画像.png

画像.png

トランザクション レビューは、ブローカーによって開始されるスケジュールされたネットワーク呼び出し (60 秒ごと) であるため、クライアントの開始時に初めてトランザクション レビューが 60 秒間隔である必要はなく、通常は 60 秒未満です (トランザクション レビューが開始されるため)ブローカーによって)、クライアントによって定期的に開始されるわけではありません)

要約する

RocketMQ は、主に 2 フェーズ コミット プロトコルを通じて分散トランザクションをサポートします。最初のフェーズでは、システムは準備されたメッセージを MQ に送信します。準備されたメッセージの送信に失敗した場合、操作は直接キャンセルされ、実行されません。メッセージの送信が成功した場合は、ローカル トランザクション (executeLocalTransaction) を実行します。成功した場合は、確認メッセージを送信するように MQ に指示し、失敗した場合は、ロールバック メッセージを送信するように MQ に指示します。第 2 フェーズでは、確認メッセージが送信されると、システム B は確認メッセージを受信し、ローカル トランザクションを実行します。確認メッセージまたはロールバック メッセージの送信に失敗した場合、ブローカーには、一意の ID に基づいてローカル トランザクションのステータスを問い合わせるポーリング メカニズムが備わっています。MQ は、準備されたすべてのメッセージを定期的に自動的にポーリングし、インターフェイス (checkLocalTransaction) をコールバックして、メッセージはローカルです。トランザクション処理に失敗しました。確認されていないすべてのメッセージについて、再試行を続行するか、それともロールバックする必要がありますか?

おすすめ

転載: blog.csdn.net/qq_28314431/article/details/133037768