2014-01-15 99 views
0

當前設置包括拿起從本地隊列中的消息並提取信息,並提出在我的SQL database.According我設計一個窗口服務處理有害消息

  1. 服務拾取消息從隊列中(我在這裏使用Peek())。
  2. 將其發送到數據庫。
  3. 如果由於某種原因,我在將其保存到數據庫時遇到異常,則消息返回到隊列中,這對我來說是可靠的。
  4. 我記錄錯誤,以便用戶可以知道問題並修復它。

異常示例:如果DBconnection在保存消息到數據庫的過程中丟失,那麼消息不會因爲它們在隊列中而丟失。我不直接從數據庫獲取確認,該消息被插入。因此,用戶可以看到日誌並確保DBconnection存在,並且每件事都是正常的,並且我們不會丟失隊列中的任何消息。

但考慮到另一種情況:我將在隊列中獲得的消息來自第三方根據標準架構。架構將保持不變,並且沒有變化。但是我已經看到了一些我在哪裏得到一些格式異常,因爲它沒有提交的消息是回到隊列。在這一點上,這條消息將成爲我的瓶頸,因爲同樣的消息被再次拿起並嘗試處理消息。每次服務會提起相同的消息並得到相同的異常。所以這個循環會無限循環,除非該消息被移除或將該消息放在隊列中。

看看刪除消息:截至目前,如果我去基於格式異常...那麼我可能是錯誤的,因爲我可能會在未來遇到一些其他異常。

有沒有一種方法可以把這個消息放回隊列最後的隊列中,而不是隊列的開始。

需要一些關於如何進一步處理的建議。

注意:隊列是事務性的。

+2

如果錯誤需要人工干預,您不會將它們移動到第二個錯誤隊列嗎? – Bill

+0

我必須去@Bill,就是這樣做的。將拆分的消息移入自己的隊列中,以便管理它們。我們每天處理數十萬條MQ消息,這是唯一可管理的方法。這會使PROD隊列運行並處理它所能做到的事情。然後我們使用Patrol來提醒我們這些隊列何時收到消息。 –

+0

@bill是否有MSMQ功能將這些消息放入故障轉移或備份隊列....或者它應該在代碼上完成。 – Macnique

回答

1

據我所知,MSMQ不會自動將消息轉儲到失敗隊列。無論哪種處理方式,只需要幾行代碼(Bill,Michael和我推薦的失敗隊列)。就失敗隊列而言,您可以簡單地創建一個名爲.\private$\queuename_fail的名稱。

Surviving poison messages in MSMQ是一個體面的文章,在這個確切的主題,它有一個示例應用程序和源代碼在最後。

private readonly MessageQueue _failQueue; 
private readonly MessageQueue _messageQueue; 
/* Other code here (cursor, peek action, run method, initialization etc) */ 

private void dumpToFailQueue(Message message) 
{ 
    var oldId = message.Id; 
    _failQueue.Send(message, MessageQueueTransactionType.Single); 

    // Remove the poisoned message 
    _messageQueue.ReceiveById(oldId); 
} 

private void moveToEnd(Message message) 
{ 
    var oldId = message.Id; 
    _messageQueue.Send(message, MessageQueueTransactionType.Single); 

    // Remove the poisoned message 
    _messageQueue.ReceiveById(oldId); 
} 
+0

謝謝你的示例,但如果_failQueue會嚴重打擊,並會導致另一個問題或某人必須手動清除這些消息。或者將它保存到文件而不是隊列是一個好主意。 – Macnique

+0

這取決於你想要什麼。你可以手動清理它,你可以讓另一個進程監視它,對它做些什麼(即繼續嘗試處理它),或者你可以將它轉儲到文件中。你必須決定在那裏做什麼。 – matth

+0

我寧願去一個文件,因爲它很容易維護,我可以看到一個消息的實際內容不像msmq,我可以使用你的代碼來測試至少如何移動到隊列結束。 – Macnique

0

如果發生錯誤,如果消息在web.config中爲您的WCF服務配置,則將其放入毒性隊列中。此外,如果您需要在某個延遲後重新處理消息,則可以配置重試隊列。

更新:讓我解釋一下要求。我們需要處理從其他系統發送的少量xml,並且必須將數據插入/更新/刪除到數據倉庫中。有時,更新請求在創建請求之前被推入隊列(由於某些外部系統依賴性)。因此,當更新請求被提取處理時,它會拋出一個錯誤(因爲該記錄在數據庫中不存在),然後在5分鐘後將其推入重試隊列中進行處理。在此時間範圍內,如果創建請求被處理併成功完成,則在執行更新請求5分鐘後,成功(因爲現在找到了要更新的匹配記錄)。 在文章中,配置更改將解釋重試隊列&所需的毒隊列。除了在WCF服務中創建事務隊列和啓用事務之外,不需要更改代碼。 Poison and Retry message handling with MSMQ using WCF Net.Msmq binding

+0

請提供一個代碼示例,說明如何以及爲什麼在您鏈接的文章中實施您的建議。 –

+0

@BarryDoyle我已經更新了細節。 –