簡體   English   中英

MSMQ + WCF-立即將郵件移到按字母順序排列的隊列中

[英]MSMQ + WCF - Immediately Move Messages to the Dead-Letter Queue

我們有一個WCF服務,用於偵聽隊列(MSMQ)上的消息。 它將請求發送到我們的Web服務器(REST API),該服務器返回HTTP狀態代碼。

如果狀態代碼在400范圍內,則我們將丟棄該消息。 這個想法是400范圍的錯誤永遠不會成功(未經授權,錯誤的請求,未找到等),因此我們不希望繼續重試。

對於所有其他錯誤(例如500-內部服務器錯誤),我們將WCF配置為將消息放入“重試”隊列。 經過一定時間后,重試隊列上的消息將被重試。 想法是服務器暫時關閉,因此請重試。

WCF的設置方式,如果我們在服務協定中拋出FaultException ,它將自動將消息放入重試隊列。

當消息導致400范圍錯誤時,我們只是吞下了該錯誤(我們只是記錄了該錯誤)。 這樣可以防止重試機制觸發。 但是,最好將消息移到死信隊列中。 這樣,我們可以通過向用戶和/或系統管理員發送電子郵件來對錯誤做出反應。

有沒有一種方法可以立即將這些不良消息移動到死信隊列中?

首先,我一直提到死信隊列。 當我發布此問題時,我還沒有意識到WCF / MSMQ會自動創建所謂的有毒子隊列。 任何無法在配置的次數內傳遞的消息都將放入毒物子隊列中。

在我的情況下,我知道某些消息永遠不會成功,因此我想立即將消息移出隊列。

解決方案是創建第二個隊列,我稱之為“毒葯”(不要與毒葯子隊列相混淆)。 我的catch塊將創建WCF客戶端的實例,並將消息轉發到該中毒隊列。 我可以重用同一個客戶端,以同時發布到原始隊列和中毒隊列; 我只需要在每個配置文件中創建一個單獨的客戶端端點。

我有兩個運行的獨立ServiceHost實例正在讀取隊列。 發生不可恢復的錯誤時,原始隊列的ServiceHost執行HTTP請求,並將消息轉發到中毒隊列。 第二個ServiceHost只需發送一封電子郵件以記錄一條消息丟失。

還有臨時錯誤超出最大嘗試次數的問題。 WCF / MSMQ自動創建一個名為<myqueuename>;poison的子隊列。 您不能通過WCF直接寫入子隊列,但可以使用ServiceHost從中讀取。 每當消息在有毒子隊列中結束時,我都將消息轉發到有毒劑隊列,並使用與原始處理程序的catch塊中使用的客戶端完全相同的客戶端。

我希望能夠在錯誤電子郵件中包含堆棧跟蹤。 由於我為所有處理程序重用了相同的客戶端和服務協定,因此我不能只是將堆棧跟蹤作為字符串傳遞(除非我將其添加到所有數據協定中)。 取而代之的是,我讓中毒處理程序嘗試再次執行代碼,這將再次失敗並吐出堆棧跟蹤。

這就是我的消息隊列的最終樣子:

MyQueue
    - Queue messages
    - Retry
    - Poison
MyQueuePoison
    - Queue messages

這種方法非常復雜。 從WCF服務處理程序中調用WCF客戶端很奇怪。 這還意味着在服務器上再設置一個隊列,並設置大量其他配置節來指定客戶端應將消息轉發到哪個隊列。

希望我已經理解了您的問題,如果這是我認為您在說的話,那么是的,但是顯然您需要對此進行編程。 但是您確實需要設置重試數量,以便MSMQ可以重試直到放棄。 或者,您可以為死信/消息創建自己的自定義隊列

http://msdn.microsoft.com/en-us/library/ms789035(v=vs.110).aspx http://msdn.microsoft.com/en-us/library/ms752268(v=vs.110)的.aspx

在這里也看看:

http://www.michaelfcollins3.me/blog/2012/09/20/wcf-msmq-bad-message-handling.html

如何處理WCF的MSMQ綁定中的消息失敗

希望這些鏈接對您有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM