6

System.Messaging API 経由で MSMQ を使用してメッセージを送受信する既存のアプリケーションが複数あります。キューは通常非トランザクションであり、MSMQ 3 と 4 が混在しています。

受信側のアプリケーションは、例外が最初に発生した時点で手動介入のためにメッセージがエラー キューに入れられる程度まで、有害なメッセージを処理します。しかし、手作業による介入の大部分は、メッセージをメイン キューに戻して別の試行を行い、その時点で成功するという単純なものであることが判明しました。そのため、そのプロセスを自動化するために、受信側に再試行機能を追加して、メッセージが所定の回数だけメイン キューに戻され、それぞれの間に所定の遅延が発生するようにしたいと考えています。

車輪を再発明するのではなく、MSMQ が提供するすぐに使用できるもの、およびこれに関する一般的なパターンやベスト プラクティス パターンを活用したいと考えています。そのために、MSMQ 4 での有害メッセージの追加サポートについて多くのことが発表されています。しかし、それらは .Net 経由で簡単にアクセスできるようには見えません。さらに、それらを使用するために私が見つけることができる唯一の参照は、MSMQ バインディングを使用した WCF を介したものです。

WCFを使用していない場合に再試行を実装するパターンや例を誰かが提案できますか?

4

2 に答える 2

7

これを行うための一般的なパターンを 1 つも見つけることができませんでした。しかし、System.Messaging を少し調べてみたところ、Message プロパティと MSMQ の動作を活用することができました。これは、可動部分を最小限に抑えて仕事を完了するための適切な方法だと思います。

これが私が実装したものです。非常にシンプルで軽量であることが判明しました。コードが少なく、保守が簡単です。

次の 3 つのプロパティを持つ RetryLevel というオブジェクトを作成しました。

int Order、int NumberOfRetries、TimeSpan Delay

受信側アプリケーションの構成に、RetryLevel のリストが含まれるようになりました。したがって、新機能は基本的に n レベルの再試行をサポートします。

次に、RetryInfo というオブジェクトを作成しました。このオブジェクトには 2 つのプロパティがあります。

int 試行回数、文字列 SourceQueuePath

RetryInfo オブジェクトのインスタンスがシリアル化され、最終的に再試行される各 Message の Extension プロパティに格納されます。これにより、メッセージ自体の現在の再試行状態を追跡できるため、別の再試行メタデータ ストアを維持する必要がなくなり、メッセージ ID の調整やデータの同期の維持などのすべてのオーバーヘッドがなくなります。

最後に、受信側の構成に待機キュー パスを追加しました。このキューは、「タイムアウト」中にメッセージがドロップされる場所です。

したがって、メッセージ ハンドラーがメッセージを拒否すると、受信者はその RetryInfo がある場合はそれを逆シリアル化し、(以前の) Attempts の数を調べて、設定された RetryLevels のどれに到達したかを判断します。

次に、受信者は Message の TimeToBeRecieved (TTBR) プロパティを DateTime.Now に適切な RetryLevel の Delay 値を加えた値に設定します。次に、AdministrativeQueue プロパティを RetryInfo の SourceQueuePath プロパティから作成されたキューに設定し、メッセージの AcknowledgeType を AcknowledgeTypes.NegativeReceive に設定します。最後に、メッセージを待機キューに入れます。

ここから、MSMQ はメッセージの TTBR を監視します。タイムアウトになると、MSMQ は、メッセージが最初に送信されたキューである AdministrativeQueue プロパティのキューにメッセージを戻します。メッセージがハンドラーによって引き続き拒否された場合、メッセージは RetryLevels を上に移動します。

メッセージの Attempts が、構成された RetryLevels のすべての NumberOfRetries の回数を超える場合、メッセージの TTBR プロパティは TimeSpan.Zero に設定され、UseDeadLetterQueue プロパティは true に設定され、メッセージは他の再試行と同様に待機キューに入れられます。ただし、今回はすぐにタイムアウトになり、MSMQ はそれを待機キューのホストのシステム デッド レター キュー (DLQ) に送り、そこで手動で処理できるようにします。

于 2013-04-09T15:28:36.327 に答える
0

車輪の再発明はしたくないとおっしゃっているように、 MassTransitなどの多くの利用可能なフレームワークの 1 つを使用することをお勧めします。

個人的には、MSMQ の上にあるNServiceBusで良い経験をしました。

これにより、エラー処理の構成が非常に簡単になります。アプリケーションの実際の作業キューを定義でき、追加で専用のエラー キューを定義できます。また、有害なメッセージを選択したキューに移動するまで、アプリケーションが (コードに対して自動的かつ完全に透過的に) 試行する回数を構成します。

これにより、次のような設定を簡単に行うことができます

これはすぐに使える機能です。

app.config構成例 (公式ドキュメントから) 、Publisher部分に注意してください。

公式ドキュメント http://images.nservicebus.com/basic_pubsub.png からの基本的なパブリッシャー/サブスクライバーの構成

WCF 以外の部分に関しては、NServiceBus は任意の .NET アプリケーションに対して同様に機能します。単純に DLL を参照するか、NServiceBus をコンテナーとして使用してアプリケーションをローカル サービスとしてホストするか、それを Windows サービスとして永続的に登録するかを選択できます。最後に、いつか気が変わって WCF に切り替えるとしたら、それもサポートされます。:-)

于 2013-03-01T16:23:20.330 に答える