転載します。https://www.cnblogs.com/zxf330301/p/10079997.html
マイクロサービスアーキテクチャでは、我々は多くの場合、注文処理の完了時に、次の場面に遭遇します:
- 再試行する、インターフェースを作成するため、最初の呼び出しのタイムアウト、および発信者回
- オーダーが作成されると、我々は在庫を控除する必要があり、インターフェイスのタイムアウトが発生し、その後、呼び出し側が再試行します
- 支払い要求の後に払って起動するには、この注文がなされると、サーバはお金の操作、インターフェースの応答タイムアウトを控除で行われた、および発信者を再試行します
- 注文状況の更新インタフェースは、呼び出し側は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} と バージョン<$ { バージョン}
|
ステートマシンコントロール
作成し、支払指図書は、支払指図書が前になければならないなど、この方法は、例ステートマシン転送の存在に適している、そして我々は、状態フィールドのデザインに渡すint型を使用し、値の種類によってすることができますサイズは、0の順序を作成するよう、冪等を行い、100支払いが成功しました。お支払いは99を失敗しました
ステートマシンの更新を行うことで、私たちはそれを制御することができます
1
|
更新 `order` 設定 ステータス=#{ ステータス} ID =#{ ID} と ステータス<#{ ステータス}
|
これらは、そのインタフェースを確保する方法はいくつかある冪等