2013-02-27 11 views
6

System.Messaging API経由でMSMQを使用してメッセージを送受信する既存のアプリケーションが複数あります。キューは一般的に非トランザクションで、MSMQ 3と4が混在しています。WCFを使用しないMSMQでの再試行メカニズムの作成

受信アプリケーションは、最初に何らかの例外が発生したときにメッセージが手動介入のためにエラーキューに入れられる。しかし、手動介入の大部分は、成功した時点で別の試行のためにメッセージをメインキューに戻すだけです。そのプロセスを自動化するために、私は再試行機能をレシーバーに追加して、メッセージがメインキューに一定の回数だけ戻されるようにしたいと考えています。

ホイールを改造するのではなく、MSMQが提供するものだけでなく、これに関する一般的な、またはベストプラクティスのパターンをそのまま利用できます。その目的のために、MSMQ 4のポイズンメッセージの追加サポートについて多くのことがあります。ただし、.Net経由で簡単にアクセスできないようです。さらに、私がそれらを使用するために見つけることができる唯一の参照は、MSMQバインディングを持つWCF経由です。

WCFを使用していない場合は、誰でもパターンを提案したり、再試行を実装する例を指摘できますか?

答えて

7

私はこれを行うための単一の普及したパターンを見つけることができませんでした。しかし、System.Messagingをちょっと調べてみると、メッセージのプロパティとMSMQの動作を活用して、最小限の可動部分で作業を完了させる適切な方法だと思いました。

これは私が実装したものです。それはかなり単純で軽量であることが判明 - あまりないコードや保守が容易:

私は3つのプロパティを持つRetryLevelと呼ばれるオブジェクトを作成しました:

int型の注文、 int型NumberOfRetries、 のTimeSpanディレイ

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

次に、RetryInfoというオブジェクトを作成しました。

INT試行、 列SourceQueuePath

RetryInfoオブジェクトのインスタンスがシリアル化と再試行されてしまう各メッセージの拡張プロパティに格納されます。このオブジェクトは、2つのプロパティを有します。これにより、メッセージ自体の現在の再試行状態を追跡することができるため、別の再試行メタデータストアを維持する必要がなくなり、メッセージIDを調整してデータを同期させるなどのオーバーヘッドが発生しません。

最後に、受信者の構成への待ち行列経路。このキューでは、メッセージが「タイムアウト」中にドロップされます。

メッセージハンドラがメッセージを拒否すると、受信者はRetryInfoがあればそれをデシリアライズし、(前回の)試行回数を調べて、到達したRetryLevelsのどれかを判断します。

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

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

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

0

あなたがホイールを再発明したくないと言うので、MassTransitなどの多くの利用可能なフレームワークを使用することをお勧めします。

個人的には、私はNServiceBusで肯定的な経験をしていますが、MSMQの上に座っています。

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

これは、あなたが簡単のようなものを設定することができます:「私は5回のリトライ以内正しくこのメッセージを処理できない場合は、私のエラー・キューに移動、その後、

これはアウト・オブ・ボックスです機能性。

(公式ドキュメントからの)例の構成は、出版社一部のapp.config注意:非WCFの部分については

Basic Publisher/Subscriber configuration from official documentation http://images.nservicebus.com/basic_pubsub.png

を、NServiceBusは、任意の.NETアプリケーションのために同じように適しています。単にDLLを参照するか、NServiceBusをコンテナとして使用してアプリケーションをローカルサービスとしてホストするか、Windowsサービスとして永続的に登録することができます。そして、最終的に、あなたがいつかあなたの心を変えて、サポートされるWCFに切り替えるのであれば、 :-)

+0

ありがとうございます。私は、WCFのように、再試行機能を持つMSMQの上に構築されたアプリケーションであるNServiceBusとMassTransitを認識しています。しかし、私の質問は、MSMQの上にアプリケーションを構築する場合、リトライ機能を作成するための良い方法です。私のアプリケーションを別のものに置き換える良い方法ではありません。 –

関連する問題