RabbitMQなどのAMQPブローカーをアーキテクチャに統合する方法を理解しようとしています。これにより、将来、水平方向に簡単にスケーリングできるようになります。
簡単にするために、アナロジーで質問させてください。
あなたが持っていると言う:
ユーザーが引き出しを開始すると、このアクションをカプセル化したメッセージがAMQP交換に送信されます。交換はメッセージをキューに入れ、このキューを消費している利用可能なワーカーの1人によってピックアップされます。
しかし、ユーザーが「すぐに」別の引き出しを開始するとどうなりますか?対応するメッセージが別のワーカーによって取得され、2人のワーカーが同じ銀行口座を同時に処理する可能性があります。
発生前の関係を保証するために、ワーカー間でどのように同期しますか?ある労働者が同じ銀行口座で働いているのを防ぐにはどうすればよいですか?
私は建築設計にかなり慣れていないので、これは一般的な質問かもしれません。私はここで私を助けるかもしれない外部の有用なリソース(本、...)に満足しています。
だから、ここに2つの問題があります
1:単一のリソース(銀行口座)での同時アクション(引き出し)の防止/解決
2:特定の順序で処理アクション(引き出し)を実施します
あなたの例では、いくつかの方法で1を解決できますが、最も簡単な方法を考えてみましょう。引き出しの処理は、リクエストを同期的に処理する銀行口座サービスで、ReduceBalance(accountId、amount)を呼び出します。
どちらが先に発生しても、バランスが取れていないために2番目に発生したものは失敗するため、気にしません。
2の解決はより複雑であり、引き出しが行われなければならない順序にいくつかのビジネスロジックがあるとしましょう。アカウントYからのものと同じ時間枠で発生するアカウントXからのもの必須最初に発生します。
まず、ワーカー間の何らかの形の通信を含むこのロジックを適用して、順序を決定する必要があります。これは、さまざまなワーカープロセス(WP)を管理し、ジョブをキューにルーティングすることだけが仕事であるMasterWorker(MW)プロセスによって最もよく達成されると思います。
さまざまなメッセージと状態はすべてキューを介して実行でき、分散非同期処理も可能です。つまり、外出先で一度に複数のメッセージセットを使用できます。唯一注意が必要なのは、一度に1MWしか実行しないようにすることです。 Rabbit MQには、使用可能なキューの排他ロックの方法がありますが、私の見解では少し不安定です。
彼は優れていますが、Ewanによって提案されたものとは別の解決策があるかもしれません。キューのプールがあるとします。いつでも、キューは空いているか(まったく使用されていない)、特定の銀行口座に割り当てられています。
使用するキューを割り当て、それを銀行口座に割り当て、次の無料の従属ワーカーが使用できるようにするには、マスターワーカーが必要です。
ここで、ワークアイテムをキューからプルするワーカーが同期メカニズムを使用して、ワークアイテムの処理中に他のワーカーがそのキューにアクセスできないようにするメカニズムがあると仮定します。作業項目が処理された後、キューは解放され、すべてのワーカーが作業できるようになります。
キューは、空になるまで1つの銀行口座に割り当てられたままになります。その後、空きになり、空きキュープールに戻ります。
これは、Ewanによって提案されたソリューションと非常によく似ています。主な違いは、より多くのキューを割り当てる必要があり、ワーカーを少なくできることです。