1

すべてのメッセージを MSMQ に到着した順に処理する必要があります。

WCF サービスをクライアントに公開します。この WCF サービスは、NServiceBus (Sendonly バス) を使用してメッセージを MSMQ にポストします。

Nservicebus を使用して MSMQ からメッセージを読み取り、データベースに保存する Windows サービス (MessageHandler) を開発します。私たちのデータベースは毎日数時間利用できません。

データベースのダウンタイム中、プロセスは MSMQ の最初のメッセージを再試行し、データベースが起動するまで他のメッセージの処理を停止することが予想されます。データベースが起動したら、メッセージが送信された順に NServicebus を処理します。

MaximumConcurrencyLevel="1" MaximumMessageThroughputPerSecond="1" を設定すると、このシナリオで役立ちますか?

このシナリオを処理するために NServiceBus を使用する最善の方法は何ですか?

4

2 に答える 2

1

すべてのメッセージを MSMQ に到着した順に処理する必要があります。

この質問への回答を参照してくださいnservicebus でメッセージの順序を処理するには? 、およびこの投稿はこちら.

順序どおりの配送は可能ですが、順序が問題にならないようにシステムを設計する方がはるかに優れていることに同意します。リンクされた記事では、次のソリューションの概要が説明されています。

  • すべてのメッセージにシーケンス番号を追加する
  • 受信側で、シーケンス番号が最後に確認された番号 + 1 であることを確認します
  • 第 2 レベルの再試行を有効にします (順序が間違っている場合は、正しいメッセージが受信された後に再試行されることを願っています)。

ただし、特定の質問に答えるために:

MaximumConcurrencyLevel="1" MaximumMessageThroughputPerSecond="1" を設定すると、このシナリオで役立ちますか?

あまり。

順序付けられた配信が必要な場合は常に、順序どおりの配信を保証するために、メッセージ処理パイプラインのどこかにシングル スレッド プロセスが必要であるという基本的な論理法則が規定されています。

これがどこで発生するかはあなた次第です ( resequencer patternを確認してください) が、確かに NserviceBus ハンドラーをシングル スレッドに絞り込むことができます (シングル スレッドにするために MaximumMessageThroughputPerSecond を設定する必要はないと思います)。

ただし、これを行ったとしても、またトランザクション キューを使用したとしても、各メッセージが順番にデキューされ、データベースに処理されることを保証することはできません。キューから削除され、次のメッセージが処理されます。

データベースのダウンタイム中、プロセスは MSMQ の最初のメッセージを再試行し、データベースが起動するまで他のメッセージの処理を停止することが予想されます。データベースが起動したら、メッセージが送信された順に NServicebus を処理します。

これはお勧めできません。NServiceBus の第 2 レベルの再試行機能は、計画的および長期的な停止ではなく、予期しない短期的な停止を処理するように設計されています。

まず、NServiceBus メッセージ ハンドラー エンドポイントが入力キュー内のメッセージを処理しようとして、データベースが使用できないことを検出すると、第 2 レベルの再試行ポリシーを実装します。これは、デフォルトで、頻度を上げながら 5 回デキューを試行し、その後永久に失敗します。 、失敗したメッセージをエラーキューに貼り付けます。その後、入力キュー内の次のメッセージに移動します。

これ自体は注文どおりの配送要件に違反するわけではありませんが、次の 2 つの理由で非常に困難になります。

  1. データベースが再び利用可能になったら、永続的に失敗したメッセージを優先して再処理する必要があります。
  2. 大量の不要な障害ログが作成され、本物の処理エラーがわかりにくくなります。

事前に知っている定期的な計画停止がある場合、それらに対処する最も簡単な方法は、スケジュールの別の用語であるサービス ウィンドウを実装することです。

ただし、Windows サービス マネージャーはサービス ウィンドウの概念をサポートしていないため、スケジュールされたタスクを使用してサービスを停止してから開始するか、 hangfireQuartz.net 、またはその他のcron タイプのライブラリなどの他のオプションを調べる必要があります。

于 2015-09-15T09:18:27.287 に答える
1

メッセージが順番に到着する必要がある理由は、種類によって異なります。最初にメッセージを受信し、次に特定の順序に属するOrderさまざまなメッセージを受信した場合、複数の可能性があります。OrderLine

OrderLine1つは、.のないメッセージが存在する可能性があることを受け入れることOrderです。Orderとにかく後で来るでしょう。結果整合性。

もう 1 つは、NServiceBus Saga でメッセージ (および可能な状態) を収集することです。通常MessageAは最初に到着する必要があり、受信MessageBしてMessageC後で受信する必要がある場合は、3 つのメッセージすべてにサガを開始する機能を与えます。3 つのメッセージはすべて、一意の GUID など、それらを結び付けるものを持っている必要があります。その後、サガはそれらを適切に収集することを確認し、すべてのメッセージが到着したら、おそらく最終状態を保存し、サガを完了としてマークします。

別のオプションは、すべてのメッセージをデータベースに直接保持し、何が何に属しているかを他の何かに理解させることです。これは、何があってもデータを収集する必要があるデータ ウェアハウスに役立つシナリオです。一部のデータは 100% 正確 (または一貫性) ではない場合がありますが、問題ありません。

非同期メッセージングでは、特に WCF を呼び出すクライアントが間違いを犯したり、順不同で送信したりする場合に、それらを 100% 順番に処理することが難しくなります。このような要件と順不同のメッセージが表示されたのは初めてではありません。

于 2015-09-16T22:10:25.917 に答える