マイクロサービスアーキテクチャでは、我々は多くの場合、注文処理の完了時に、次の場面に遭遇します:
- 再試行する、インターフェースを作成するため、最初の呼び出しのタイムアウト、および発信者回
- オーダーが作成されると、我々は在庫を控除する必要があり、インターフェイスのタイムアウトが発生し、その後、呼び出し側が再試行します
- 支払い要求の後に払って起動するには、この注文がなされると、サーバはお金の操作、インターフェースの応答タイムアウトを控除で行われた、および発信者を再試行します
- 注文状況の更新インタフェースは、呼び出し側は1が支払われ、1が作成された、行の2つのメッセージを送信します。しかし、最初に、あなたは支払いを受けた後、作成されたことを受けてきました
- 支払指図の完了後、あなたがメッセージを送信する必要があり、機械のSMSメッセージを受信した後、プロセスが遅いです。別のマシンの処理に再び配信されるメッセージのミドルウェアメッセージ
上記の問題は、モノマーサービスアーキテクチャのマイクロアーキテクチャに変身したら、問題をもたらします。もちろん、これらの問題のいずれもフレームワークモノマーの下で、同じ枠組みの中での単量体は、複製要求を避けないようにと言うことではありません。しかし、問題はこれよりもはるかに少ないです。
この問題を解決するために、我々はその冪等のインターフェースを確認する必要があり冪等のインターフェースを、インターフェースが実際に呼び出しを繰り返され、呼び出し元に複数の呼び出しの場合には、結果が最終的にインターフェイスには一貫性があります。いくつかのインタフェースは、このようなクエリインターフェイスなどの自然冪等を、達成することができ、クエリのために、あなたは一度や二度照会し、システムのために、何の効果、孤立結果は同じではありません。
検索機能に加えて、自然の冪等があり、追加、更新、削除冪等を確認する必要があります。それでは、どのよう冪等にそれを確保するには?
グローバル一意のID
グローバルに一意のID、及びサービスの内容が動作している場合、グローバルIDは、操作が行われたかどうかを決定するために存在するグローバルに一意のIDに応じて操作を実行する前に、に従って生成されます。ストレージシステムに格納されているグローバルIDを、そこに置かれている場合は、データベースなど、Redisのが好きです。メソッドが実行されたことを示しているがある場合。
エンジニアリングの観点からは、グローバルID、などの使用はマイクロサービスに基づいてビジネスを行うための電源として使用することができ、このようなサービスで使用される多くのマイクロサービスに存在し、そのような機能は、各マイクロサービスに完成され、意志ワークロードが繰り返されます。また、信頼性の高い電源を作成し、他のサービスは、グローバルIDは、メモリを書くことが、このような機械など多くの問題を、検討する必要がありますが、タイムアウトメカニズムのグローバルIDの導入を必要とする、書き込み後にハングアップします。
グローバルに一意のIDを使用することにより、業務を削除、挿入、更新をサポートすることができ、一般的なソリューションです。しかし、このプログラムの実現は美しく見えるが、あまりにも面倒、以下のスキームは、特定の場面に適用されますが、実装が簡単。
重複除外テーブル
順序は一度だけ支払われる場合は、この方法では、例えば上で決済シナリオのように、事業のユニークな対象とシーンに挿入するのに適しているので、あなたは、一意の識別子としてIDを注文することができます。この時点で、我々は重いテーブルを構築するために行くことができる、ユニークなインデックスとして固有の識別、我々が実現する場合、文書を作成すると、データベースの意志を再作成した場合、トランザクションで、重いテーブルを支払うことを何度も何度も書かれており、唯一の制約が例外をスローし、操作がロールバックされます。
挿入または更新
この方法では、ケースを有し、一意のインデックスを挿入し、我々は製品IDとカテゴリIDが一意のインデックスを構成することができる、請求商品のカテゴリ、およびテーブル内のデータを関連付けるようにも一意のインデックスを増加させます。そして、あなたはInsertOrUpdate操作を使用することができます。MySQLデータベースでは、次のように:
1
2
3
4
|
挿入 goods_categoryに(goods_id、CATEGORY_ID、CREATE_TIME、UPDATE_TIME)
値(#{goodsId}、{#区分}、今()、NOW())
上の DUPLICATE KEY UPDATE
UPDATE_TIMEは=
NOW()
|
マルチバージョン
この方法では、我々は冪等を行い、更新インターフェースにバージョン番号を追加することができ、例えば、我々は、商品の名前を更新する、更新されたシナリオに適しています
1
|
ブール updateGoodsName (int型のID、文字列NEWNAME、INTバージョン);
|
実装された場合、以下のようにしてもよいです
1
|
更新商品が セット 名=#{NEWNAME}、バージョン=#{ バージョン} ここで、 ID =#{ ID} とバージョン<$ { バージョン}
|
バージョンによって達成1.
更新がセット名table_xxx =#名位 、バージョン=バージョン+ 1ここで、バージョン=#バージョン番号
(インターネットから)以下:
2.条件
設定table_xxx更新avai_amount = avai_amount-#subAmount #ここavai_amount - #subAmount#> = 0
要件:quality-#subQuality#> =、このシナリオのバージョン番号に適合しない、更新は、在庫モデル、バックルシェアと共有ロールバック用のデータセキュリティチェック、高いパフォーマンスのためのものです
。注:楽観ロック更新動作は、好ましくは、更新された主キーまたは一意のインデックスと、この行がロックされている、または更新ロックテーブルは、次の2つのSQLより良好に上記の二つの場合に
更新がセット名table_xxx =#名位 、バージョン= ID =バージョンID#および## =バージョンVersion#+。1
更新SET table_xxx avai_amount = avai_amount- subAmount ### WHERE ID = avai_amount- ID#および## subAmount> = 0
ステートマシンコントロール
作成し、支払指図書は、支払指図書が前になければならないなど、この方法は、例ステートマシン転送の存在に適している、そして我々は、状態フィールドのデザインに渡すint型を使用し、値の種類によってすることができますサイズは、0の順序を作成するよう、冪等を行い、100支払いが成功しました。お支払いは99を失敗しました
ステートマシンの更新を行うことで、私たちはそれを制御することができます
1
|
更新 `order` 設定 ステータス=#{ ステータス} ID =#{ ID} と ステータス<#{ ステータス}
|
これらは、インターフェースなどの電源を確保する方法はいくつかあります。
冪等を確認し、外部インタフェースのAPIを提供する方法10.
支払いインターフェースを提供するために、そのような銀聯などを:アクセスが商人の支払い要求を提出する必要がある場合に来る:ソースソース、SEQシリアル番号
ソース+ SEQは(複数の支払いを防ぐために、データベース内で一意のインデックスを作成します同時、唯一の要求)を処理することができ
、フォーカスを:
、合格しなければならない冪等呼び出しインタフェースは、2つのフィールドを有するサポートするための外部インターフェイスを提供するソースのソースであり、ソース側のシリアル番号は、配列され、プロバイダシステム内の2つのフィールドサードパーティのコールは、最初に内部ローカルシステムをチェックするときにのみインデックスを処理するかどうか、関節行うために、対応する結果に戻り、に対処し、それに応じて扱われていない、結果を返します。注文冪等の友情に、このトランザクションを処理するかどうかを問い合わせるようにしてくださいことに注意してください、ビジネスシステムに直接照会しません文句を言うだろうが、実際に処理されています。
概要:
冪等は、システムの設計では、遺伝子の修飾プログラマである第一に考慮され、特に宝物、銀行、金融会社や他のインターネットに関わるすべてのお金を払うようなシステムでは、それは効率的なデータに必要である必要があります正確である必要があり、それはチャージバックより多く表示され、より多くのお金やその他の問題を再生することはできません、それが困難扱うようになり、ユーザ体験は良いではありません