システムの設計上の問題を解決するためのアイデア/パターンを探しています。まもなく作業を開始します。システムの特定の領域間で通信するために、ある種のメッセージング(おそらくMSMQ)を使用する必要があることは間違いありません。車輪の再発明はしたくありませんが、同時に、仕事に適したツールを使用していることを確認したいと思います。私はNServiceBusをいじくり回して読んでいて、それが何をするのか非常に感銘を受けていますが、それが私が達成しようとしていることを意図しているのかどうかはわかりません。
これは、システムが実行する必要があることの(うまくいけば)非常に単純で概念的な説明です。
クライアントがメッセージを送信できるサービスがあります。サービスは「ファイアアンドフォーゲット」です。クライアントが返す可能性が最も高いのは、成功または失敗を示す可能性のあるものです(成功とはメッセージが受信されたことです)。
各メッセージの処理/処理は重要であり、かなりのシステムリソースを消費する可能性があります。このため、同時に処理できるのはXメッセージのみです。Xは構成可能な値です(システム仕様などに基づく)。着信メッセージは、処理される「順番」になるまでキューに保存されます。
クライアントごとに、メッセージを順番に処理する必要があります(FIFO)。ただし、一部のクライアントは、たとえば一定期間接続が失われた場合など、多数のメッセージを連続して(数千以上)送信する場合があります。このため、メッセージはクライアント間でラウンドロビン方式で処理する必要があります。つまり、クライアントがゴージしたり、飢えたりすることはできません。したがって、システムは特定のクライアントのキューを照会するか、クライアントごとに個別のキューを作成して(コンパイル時にクライアントが認識されないため、自動的に)、それらから順番にプルする必要があります。
私の現在の考えは、実際にはバニラMSMQを使用し、メッセージを受け入れて1つ以上のキューに書き込むサービスを作成し、キューからメッセージを読み取って処理/処理するプロセスを作成する必要があるということです。ただし、NServicebusのようなもので得られる信頼性、監査、拡張性、および構成の容易さは非常に魅力的に見えます。
ESBはその仕事にとって間違ったツールですか?私が見なければならない他の技術やパターンはありますか?
アップデート
いくつかの説明。
「順番に」メッセージを処理することに関して-単一のクライアントのコンテキストでは、メッセージは受信された順序で絶対に処理される必要があります。正確な理由を説明するのは複雑ですが、これは確固たる要件です。クライアントごとに1つのメッセージだけが同時に処理されることになると言うのを怠りました。したがって、10個のワーカースレッドがあり、処理を待機しているメッセージが1つのクライアントだけであったとしても、一度に処理されるのはそれらのメッセージの1つだけであり、競合状態の心配はありません。
これは一般的にバニラMSMQで可能であると思います。つまり、メッセージのリストをキューに入れて、常に最も古いものを最初に取得することができます。
また、ラウンドロビン注文のユースケースを明確にしたいと思いました。この例では、メッセージを送信する2つのクライアント(AとB)と、1つのワーカースレッドしかありません。すべてのキューが空です。クライアントAは一晩で接続を失ったため、午前8時にサービスに1000件のメッセージを送信します。これらのメッセージはキューに入れられ、ワーカースレッドは最も古いメッセージを取得して処理を開始します。この最初のメッセージが処理されている間、クライアントBはメッセージをサービスに送信します。サービスはキューに入れられます(前述のように、おそらく別のキューにあります)。クライアントAの最初のメッセージの処理が完了すると、ロジックはクライアントBにメッセージがあるかどうか(クライアントBの「ターン」)をチェックし、メッセージが見つかったので次に処理する必要があります。
その間にクライアントBがメッセージを送信しなかった場合、ワーカーはクライアントAのメッセージを一度に1つずつ処理し続け、処理後に常に他のクライアントキューに待機中のメッセージが含まれているかどうかを確認して、クライアントが不足していないことを確認します。
ESBとこの問題の間に不一致があるかもしれないと私がまだ感じているのは、ESBがサービス間の通信を容易にするように設計されていることです。私が達成しようとしているのは、メッセージング/通信と選択的キューイングシステムの組み合わせです。