MSMQ:メッセージがエラーなしで送受信されないことがある
-
20-12-2019 - |
質問
MSMQ に次のセットアップと問題があります。MSMQ に関するこれまでの経験に基づいて、これは私に欠けている単純な何かであると確信していますが、それが何なのかはわかりません。
セットアップ
負荷分散された 3 つの Web サーバーがあります (これらをサーバーと呼びます) W1, W2 そして W3) と、Web リクエストから離れて特定のイベント/データを処理する 1 つのサーバー (これを私は呼びます) P)。Web アプリケーション内で特定のイベントが発生すると、3 つの Web サーバーすべてがサーバー上のリモートのプライベート キューにメッセージを送信します。 P, 、キューからの各メッセージを処理し、何らかのタスクを実行します。
問題
ほとんどの場合 (推定 95% の確率で) すべてが正常に動作しますが、場合によってはサーバーが正常に動作しないことがあります。 P Web サーバーからメッセージを受信しません。これはどちらかの理由です W1, W2 または W3 送信していないか、受信していません。 P, 、私にはわかりません。これは、Web アプリケーションでユーザーから発生した重要なイベントが欠落しているのに、自分のログにはエラーがリストされていないことを意味します。
詳細
ここでは、私の設定とこれまでにわかったことを説明するのに役立つと考えられるすべての詳細を示します。
- サーバー上のプライベートキュー P 非トランザクションです。
- プライベート キューには次の権限が設定されています みんな メッセージの送信と受信の両方に。
これは、リモートのプライベート キューにメッセージを送信するために使用するコード (C#) です。
var queue = new MessageQueue(@"FormatName:DIRECT=OS:ServerP\PRIVATE$\MyMessageQueue"); var defaultProperties = queue.DefaultPropertiesToSend; defaultProperties.AcknowledgeType = AcknowledgeTypes.FullReachQueue | AcknowledgeTypes.FullReceive; defaultProperties.Recoverable = true; defaultProperties.UseDeadLetterQueue = true; defaultProperties.UseJournalQueue = true; queue.Send(requestData);
上記のコードを使用してメッセージを送信しても例外はスローされないようです。例外がスローされた場合は、Web アプリケーションのエラー ハンドラーがそれを捕捉してログに記録したはずです。そのため、例外は送信されたと思います。
- に発信キューがあります W1, W2 そして W3 すべてはプライベートキューを指しています P - これらはすべて空です。
- の上 W1, W2 そして W3 「デッドレター」メッセージが表示されません。
- の上 P プライベート キューは空であるため、メッセージが処理されています (これはデータベースから確認できます)。
- の上 P 「デッドレター」メッセージはありません。ジャーナルメッセージはありますが、最近の日付/時刻に対応していないようです。
- すべてのサーバーで Windows Server 2012 が実行されています。
ほとんどの場合、メッセージは問題なく送信、受信、処理されますが、パターンが表示されずに、そうでない場合もあります。何が問題になっているのかわかる人はいますか?それとも、何が起こっているのかを調べる方法を教えてください。
解決
P 上の受信者が何らかの理由でクラッシュしたり、メッセージを失ったりしないことを確信していますか?キューはトランザクション型ではないため、何らかの理由で処理が失敗した場合、それは 1 つのメッセージが失われたことになります。
いずれにしても、これが失敗する原因は数多く考えられます。どのような種類のログ (DEBUG/INFO レベル) がありますか?
以下が問題の追跡に役立つと思います。
- Web アプリでイベントが生成されたとき。
- Web アプリから MSMQ 経由でイベントを送信する直前。
- キューからメッセージを取得するときのレシーバー内。
この方法により、少なくとも送信メッセージと受信メッセージおよび処理済みメッセージを一致させることができます。
補足として、デッドレター メッセージをチェックするときは、宛先コンピュータではなく、送信元コンピュータと中間ホップでチェックします。ホップがない場合、ホップは Web サーバー上の非トランザクション配信不能キューに中継されます。