トランザクションメッセージを実装する方法の詳細な分析

これは、私はあなたが好きなことを願っています昨年書いた記事からの記事です

1.背景

分散トランザクションは、私の電話番号、次の次のパブリックにおける共通のテーマは、多くの記事分散トランザクションに関連する記事を書かれていてきましたが、まだ完全に解析することがありません。前回の記事で、私たちは私たちの分散トランザクションを実装するために、メッセージ・キューを使用することができることを何度も言及しているが、ほとんど通過して、多くの読者は、この1は、多くの質問があった、あなたがこの記事を読みたい作りますメッセージキューで分散トランザクションを実装する方法を理解しています。

もちろん、我々は最初に私たちの基本的な概念のいくつかを見なければなりません。

キャップ

また、ブリュワーの定理として知られているCAP定理、。建築家の分散システムの設計(だけでなく、分散トランザクション)のために、CAPは、あなたの入門理論です。

  • C(一貫性):特定のクライアントのために、読み出し動作は、最新の書き込み操作を返すことができます。更新されたデータ内のノードが、そのほかのノードが最新のデータを読み取ることができる場合場合、別のノードに分散されたデータについては、存在する場合、ノードが読み取りを持っていない、強力な合意と呼ばれ、取る、それは矛盾が配布されます。
  • (使用可能):妥当な時間内に妥当な(そしてエラーレスポンスタイムアウト)に応答して返さ良品ノード。二つのキーは、合理的な時間の可用性が合理的応答です。要求が無期限にブロックされないことができる時間手段の合理的な期間、復帰は、合理的な時間内に与えられるべきです。合理的な応答は、結果クリア戻ることが、結果は、そのようなリターンを指す右ここで、正確でなければならないシステムを指し50ではなく40リターンであるべきです。
  • P(パーティションフォールトトレランス):ネットワークパーティションが発生した場合、システムは動作し続けます。クラスタが複数のマシンを持っている比喩は、マシンがネットワークの問題を持っていますが、クラスタはまだ動作することができます。

CAPの証明を検索することができます興味を持って、分散システムでは、ネットワークの信頼性が100%にならないことができれば慣れている人は知っているCAPは、我々はCA Pを放棄することを選択した場合、パーティションは、実際には自然現象であり、3がありませんパーティションが発生したときに、一貫性を確保するために、この時間は、要求を拒否しなければならないが、Aは許可していない分散システムは、CAのアーキテクチャを選択することは理論的に不可能である、あなただけのCPやAPのアーキテクチャを選択することができます。

CPについては、一貫性およびパーティションフォールトトレランスの追求を放棄する可用性、および強力な飼育係は、私たちの追求と、実際に一致しています。

APの場合は、一貫性をあきらめて(ここでは一貫性が強い一貫性であると言う)、パーティションのフォールトトレランスと可用性の追求が、これはまた、APに応じて拡張することがBASEに続く多くの分散システムの設計の選択が、あります。

ちなみに、CAPは、ノードAからノードBへコピーしたトランザクションのコミット、あるネットワーク遅延の理論を、無視することですが、実際にはこれは明らかに不可能であるので、一定の時間が矛盾して常にあります。同時に、CAPとは、例えば、あなたがCPを選択し、2を選択し、Aを放棄するあなたを教えてくれません Pの発生確率が小さすぎるため、ほとんどの時間は、あなたはまだCAを確認する必要があります あなたはログの数によって、たとえば、後でAの準備をするために登場したパーティションに持っていたとしても、それは他のマシンに対応するために利用可能です。

ベース

BASEは、(利用可能な基本的な)基本的には利用可能で、ソフト状態(ソフト状態)と最終的には一貫性のある(結果整合性)3句を省略。CAPは、APの拡張であります

基本的な利用可能:障害が発生した場合の分散システムでは、利用可能な機能のいくつかの損失を許容するコア機能が使用可能であることを確認します。ソフト状態:システムが中間状態を許し、これはシステムの可用性ステータスには影響を与えませんが、ここCAPで矛盾していると呼びます。最終合意:時間をかけて、すべてのノードはすべて同じデータを持っていることを最終合意手段。

BASE CAPは、理論的には遅延の一貫性を確保するため、ネットワークの待ち時間、柔らかい状態とBASEと最終的には一貫性を解決しません。酸と塩基が反転され、それは完全に異なるモデルACID強い一貫性であるが、利用可能性が強い整合性を犠牲にして得られたデータは、時間の経過とともに失われることができ、最終的に一貫性のある状態に達しています。

Transactionメッセージ

私たちのトランザクションメッセージのすべてが達成BASEモデルとみなすことができます。そこ業界トランザクションメッセージングでは、オープンソースのQMQにオープンソースRocketMQアリと場所のより代表的である、それらの両方がメッセージを達成しているキュートランザクション・メッセージングていますが、それは異なっている達成するための方法、それぞれ次の意志この分析はどのように2つのメッセージ・キューのトランザクションメッセージです。

2. RocketMQ-取引メッセージ

最後にRocketMQトランザクションメッセージは、それがどのようになるのですか?

基本的なプロセスは以下の通りである:調製した第1段階のメッセージは、メッセージのアドレスを取得します。地元の事務の実施の第二段階。第一段階の第三段階のメッセージのアドレスへのアクセスを取得し、状態を変更します。メッセージ受信者は、このメッセージを使用することができます。確認のメッセージが失敗した場合、それは差出人rocketmqにリスナーの形で、提出するかどうかを判断するために、メッセージの送信者にメッセージを送信し、メッセージが確認されていない場合は、更新されていないメッセージステータスの走査タイミングでRocketMqブローカーを提供処理のため。

確認のメッセージが失敗した場合、それは差出人rocketmqにリスナーの形で、提出するかどうかを判断するために、メッセージの送信者にメッセージを送信し、メッセージが確認されていない場合は、更新されていないメッセージステータスの走査タイミングでRocketMqブローカーを提供処理のため。

消費者のタイムアウトした場合は、再試行されている必要があります、メッセージの受信機は、電源などを確保する必要があります。メッセージコンシューマに障害が発生した場合は、そのような小さな確率のための時間、この複雑なプロセスの設計が、価値がろうそくその場合、これは、確率を下げるために、手動処理が必要になります

そして、あなたが他の場所で何度も見ている必要があります。この図は、多くの時間がだけにして、次の、この図から少し知識を参照し、コードがそれを実装する方法を確認してください。

2.1を使用するトランザクションメッセージ

TransactionListenerトランザクションメッセージRocketMQに呼ばれる非常に重要なリスナーがあり、我々は彼ことを認識する必要があります

2つの方法があります。

  • executeLocalTransaction:名前は一般的に、私たちのローカル・トランザクション・メソッドの実装を示唆するように、我々のアプローチは、トップビジネスの順序によって呼び出されるローカル・トランザクションを促進することであるが、あなたはRocketMQ取引メッセージのニーズを使用したい場合は、トランザクション・メッセージにrocketMQは、リスナーによって駆動する必要があります当社の事業変革の特定。そしてまた、我々はまた、メッセージのトランザクションIDと取引における現在のトランザクションとの対応を保存する必要があることに注意することが必要です。

  • checkLocalTransactionは:ここでは私たちの地域、州内の事務の状態を確認するために私たちの前のトランザクションIDによると、3つあります:3回の国政ニュース、提出状況、ロールバック状態、中間状態があります。

    • TransactionStatus.CommitTransaction:消費者がメッセージを消費することを可能にするトランザクションを、コミット。
    • TransactionStatus.RollbackTransaction:ロールバックメッセージは削除され、消費されることが許されないであろうことを意味取引、。
    • TransactionStatus.Unknown:状態を決定するために、メッセージキューをチェックする必要性を表す中間状態、。RocketMQは頻繁に点検、単一のメッセージを15回に制限され、デフォルトではチェックの数を防ぐために、チェックを再試行するときに、この状態に戻ります。

私たちの次のコードにメッセージを送信します:

私たちは、スレッドプールの役割は、私たちcheckLocalTransactionが使用するスレッドプールのある私たちのリスナーと同様にバインドするスレッドプールとコードで私たちのプロデューサー、前に自分自身を見つけます。

2.2原則

2.2.1クライアント

ここでのコードは、手順を実行する主な点は比較的簡単です

  • ステップ1:最初のブローカーにメッセージを送信します。
  • ステップ2:送信は、地元の事務の実施に成功した場合、ローカルトランザクションかどうかを判断するために送られた結果によります。
  • ステップ3:レコードは私たちが話している状態がここに提出ローカル事務の状態は、トランザクションの上にある、トランザクションはバック、中間状態三つの状態巻かれています。
  • ステップ4:トランザクションの終了がコミットまたはローカル事務の状態に応じて決定をロールバックされます。

checkLocalTransactionの場合:

RocketMQ-BrokerはRocketMQがで送信された受信 CHECK_TRANSACTION_STATE 要求、ローカル・トランザクション・ステータス・チェックが行われます。

2.3.1サーバー

トランザクションメッセージは、特別なブローカーで判断されます。

トランザクションメッセージは、あなたが行く必要がある場合はprepareMessage、次のようにこのロジックに、prepareMessageこのロジックは次のとおりです。

主なトピックは、に現在のメッセージを交換することですRMQ_SYS_TRANS_HALF_TOPICここでは、ステージに半分のメッセージを送った次のステップは、ブローカーは、私たちの業務は、ロールバックコミットまたはハンドルで、完了です。

赤いボックスは、3段階の合計をコミットするために、当社のコア・ステップを表します。

  • 半分メッセージのニーズをコミットするには、Get
  • 元トピックにメッセージを送信
  • メッセージの半分を削除します。

2段階のロールバック合計:

  • ロールバックの半分メッセージのニーズをゲット
  • メッセージの半分を削除します。

これは基本的にロジックを再利用することができ、元のトピックにメッセージを送信するために記録オフセット直接を通じてクエリのように、比較的簡単であるというメッセージを取得するには、順番RocketMQで書かれたメッセージ、我々はすべて知っているの半分を削除する方法に焦点を当てるためにここにいます我々は、それがリセットされない限り、オフセットとして、我々はニュースの消費の後に考えることができますいくつかの他の方法に頼ることができるだけで、実際にメッセージを削除するために行くことができない、このニュースが消費されることはありませんので、実際に削除された達成機能。思考のこのラインによってRocketMQは過ごすために、彼は消費者を実現していることでRMQ_SYS_TRANS_HALF_TOPIC削除されていない場合、消費者が再ルーティングされた後、消費者は、他の操作を行う必要はありません場合は、メッセージが除去される必要がある、その後場合は、このトピックを。

ことは、のコアがどのようにメッセージがそれの半分を削除すべきかどうかを記録するために、ということでしょうか?そのことについてRocketMQは、新しいトピックを採用RMQ_SYS_TRANS_OP_HALF_TOPIC半分メッセージが実際には、削除されて保存するために、上記のメッセージフローの削除半分がする実際にあるRMQ_SYS_TRANS_OP_HALF_TOPICop_messageを提供し、バックグラウンドタスクによって運営行きます。

下に示すように、全体の工程図。

  • ステップ1:また、本明細書halfMessage呼ば取引メッセージを、送信するには、トピックのHalfMessageトピックを置き換えられます。
  • ステップ2:クエリが存在する場合、送信は、コミットまたはロールバックは、前のメッセージをコミットし、現在のメッセージを削除することができ、その後OpMessageを記録して送信するために使用された元のメッセージトピック、それを復元します。ロールバックがある場合は、削除OpMessageに直接送信されます。
  • ステップ3:そこOpMessageであり、状態が削除された場合は、このメッセージを削除することができますので、ブローカーのメッセージ処理サービスでは、通常のタスク、タイミングとOpMessage halfMessageコントラストがあり、ニュース記事は、コミットまたはロールバックしなければなりません。
  • ステップ4:トランザクションタイムアウトの場合は(デフォルトは6Sである)、opMessage、それが失われた情報をコミットする可能性があり、ここでは地元の事務プロデューサーの状態のペッグ行かれていません。
  • ステップ5:ステップ2に係る情報をチェックアウトします。

2.3まとめ

すでに述べたように確かに、我々はすでにRocketMQ情勢ニュースの私たち自身の理解を持って、トランザクションメッセージと実装の原則のRocketMQを使用する方法について話しました。しかしRocketMQトランザクションメッセージは、現在、実際の戦闘で私のビジネスのいくつかは、いくつかの側面がある主な理由は、使用されることはありません。

  • このような単一の操作などの大改修工事の費用、一般的には地元の事務の順序を作成するためには、あなたが注文IDを取得します作成した後に、同時に行われるが、このRocketMQで現地情勢で、その後、リスナーの内部で動作可能となっていますそれはパラメータに戻すことはできません、サービスロジックは、このようなようにThreadLocalのようないくつかの他の手段により達成することができます。
  • TransactionIdのは、国家と地方の事務との間の関係を記録する必要があります
  • 私が欲しいの一貫した取引をする場合、メッセージの10種類を送信するために作成する必要がある場合にのみ、単一のトランザクションメッセージをサポートし、RocketMQがサポートされていません。

要約すると、私の意見では、トランザクション・メッセージのRocketMQは本当に多くの無味属し、古いビジネスに適応することは困難です。だから、どのように我々はそれを呼び出す、この問題を解決することができ、このプログラムを見て、次のソリューションQMQ取引メッセージについて話をしますか?

3. QMQトランザクションメッセージ

QMQ RocketMQトランザクションメッセージはそう、独自のローカルデータベースは、作成順序として、あなたがメッセージの2種類を送信する必要があり、トランザクションに依存自体が小さいミドルウェアメッセージングの形質転換のために、複雑ではありません、そこ、AとBです次の擬似コード:

begin transaction;
createOrder();
commit transaction;

sendMessageA();
snedMessageB();
复制代码

私たちは、メッセージが本物とメッセージングミドルウェアに対処する必要はありません送信されたときに我々はAとBが取引メッセージの外にあり、一貫性が保証できないメッセージを、見つける、この時間は、実際には、我々は地元の店、保存を行うことができます私達のニュース:

begin transaction;
createOrder();
saveMessageA();
saveMessageB();
commit transaction;
// 发送消息
sendMessageA();
snedMessageB();

复制代码

実際には、我々は、我々は時間がMessageAがハングアップして送信されたならば、私たちが行くことができると私たちは私のデータベースに格納されたメッセージを持って、定期的なタスクを介して送信されていない、それの一貫性を確保するために、どのようにしているだけのメッセージを保存するために2つの操作を追加見ることができますし、再度試してください。

実際、メッセージングミドルウェアのために自身が侵略されていないため、これと同じ方法は、他のメッセージ・キューに拡張することができ、かつRocketMQやカフカは、トランザクションメッセージを確実にするために、このメソッドを使用する場合は、も可能です。

このアプローチで見てみましょう、それを持って来るに問題RocketMQトランザクションメッセージを解決することができますか?

  • 変換コスト、1つのクライアントだけの変換、ばねTransactionSynchronizationに書き換えQMQ、以下のようにコードを直接簡略化することができます。
begin transaction;
createOrder();
sendMessageA();
snedMessageB();
commit transaction;

复制代码

ここでは、実際に内部ロジックがsaveMessageで送る、それはコミット後に自動的に送信され、バックグラウンドタスクのタイミングは、補償を送りました。

  • そして、のtransactionIdの追加の結合メッセージを必要としません
  • 複数のトランザクションをサポートするためのメッセージを送ります

基本的なトランザクションのメッセージを持って問題RocketMQを解決することができるが、それはまた、追加のデータベース書き込みを紹介するため、トランザクションメッセージが多い場合、それは書き込みデータベース操作、サービスに敏感な応答時間をより多くなり、欠点を持っていますこれは、慎重な検討が必要です

4.まとめ

2つのトランザクションメッセージを紹介し、個人的に私のために、QMQプログラムは、ほとんどのビジネスにもっと適応を達成することができます。しかし、すべての分散トランザクションメッセージの一貫性のを使用することができ、シーンにのみ使用されるトランザクションメッセージとすることができることをここで注意すべき点は、このメッセージは、それがどういう意味、この動作シナリオの成功を表すことができ、送信されましたか?たとえば、私たちが支払うときなどは、私が送信した場合のポイント控除を表現するメッセージが成功しなければならない差し引かポイント控除クーポンなどでしょうか?ユーザーは、控除の故障につながる統合ない可能性があるので、これは確かに、動作しません。あなたは贈り物は、あまりにも多くの制限が加えの不可欠な部分であり、そしてないのでギフトポイントは、成功を表現できるというメッセージを送信している場合。

あなたもご用意し、ビジネスシーンを満たすことができないトランザクションメッセージを見つけた場合、あなたは、このような私が言われてきたこれらの記事前TCC、佐賀、などいくつかの他の取引戦略を考えることができます。

あなたはあなたにこの記事が参考に思われる場合は、あなたの関心と転送が私の最大の支援で、O(∩_∩)O:

おすすめ

転載: juejin.im/post/5e0d56b2e51d4540f462f0b2