すべてのメッセージを MSMQ に到着した順に処理する必要があります。
この質問への回答を参照してくださいnservicebus でメッセージの順序を処理するには? 、およびこの投稿はこちら.
順序どおりの配送は可能ですが、順序が問題にならないようにシステムを設計する方がはるかに優れていることに同意します。リンクされた記事では、次のソリューションの概要が説明されています。
- すべてのメッセージにシーケンス番号を追加する
- 受信側で、シーケンス番号が最後に確認された番号 + 1 であることを確認します
- 第 2 レベルの再試行を有効にします (順序が間違っている場合は、正しいメッセージが受信された後に再試行されることを願っています)。
ただし、特定の質問に答えるために:
MaximumConcurrencyLevel="1" MaximumMessageThroughputPerSecond="1" を設定すると、このシナリオで役立ちますか?
あまり。
順序付けられた配信が必要な場合は常に、順序どおりの配信を保証するために、メッセージ処理パイプラインのどこかにシングル スレッド プロセスが必要であるという基本的な論理法則が規定されています。
これがどこで発生するかはあなた次第です ( resequencer patternを確認してください) が、確かに NserviceBus ハンドラーをシングル スレッドに絞り込むことができます (シングル スレッドにするために MaximumMessageThroughputPerSecond を設定する必要はないと思います)。
ただし、これを行ったとしても、またトランザクション キューを使用したとしても、各メッセージが順番にデキューされ、データベースに処理されることを保証することはできません。キューから削除され、次のメッセージが処理されます。
データベースのダウンタイム中、プロセスは MSMQ の最初のメッセージを再試行し、データベースが起動するまで他のメッセージの処理を停止することが予想されます。データベースが起動したら、メッセージが送信された順に NServicebus を処理します。
これはお勧めできません。NServiceBus の第 2 レベルの再試行機能は、計画的および長期的な停止ではなく、予期しない短期的な停止を処理するように設計されています。
まず、NServiceBus メッセージ ハンドラー エンドポイントが入力キュー内のメッセージを処理しようとして、データベースが使用できないことを検出すると、第 2 レベルの再試行ポリシーを実装します。これは、デフォルトで、頻度を上げながら 5 回デキューを試行し、その後永久に失敗します。 、失敗したメッセージをエラーキューに貼り付けます。その後、入力キュー内の次のメッセージに移動します。
これ自体は注文どおりの配送要件に違反するわけではありませんが、次の 2 つの理由で非常に困難になります。
- データベースが再び利用可能になったら、永続的に失敗したメッセージを優先して再処理する必要があります。
- 大量の不要な障害ログが作成され、本物の処理エラーがわかりにくくなります。
事前に知っている定期的な計画停止がある場合、それらに対処する最も簡単な方法は、スケジュールの別の用語であるサービス ウィンドウを実装することです。
ただし、Windows サービス マネージャーはサービス ウィンドウの概念をサポートしていないため、スケジュールされたタスクを使用してサービスを停止してから開始するか、 hangfire、Quartz.net 、またはその他のcron タイプのライブラリなどの他のオプションを調べる必要があります。