簡體   English   中英

在MSMQ中處理有毒消息

[英]Handling poison messages in MSMQ

根據我的設計,當前安裝程序包括一個Windows服務,該服務從本地隊列中提取一條消息並提取信息並將其放入我的SQL數據庫中。

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

異常示例:如果在將消息保存到數據庫的過程中DB連接丟失,則消息不會像在隊列中那樣丟失。我不承諾直到從數據庫獲得插入消息的確認。用戶可以查看日志並確保存在DBconnection,並且一切正常,並且我們不會在隊列中丟失任何消息。

但要考慮另一種情況:我將要排隊的消息是從第三方根據標准模式生成的。該模式將保持不變,並且沒有任何變化。但是我已經看到一些出現格式異常的地方,並且由於未提交消息,因此該消息將返回隊列。這時,這條消息對我來說是一個瓶頸,因為再次拾取相同的消息並嘗試處理該消息。每次服務都將拾取相同的消息並會遇到相同的異常,因此除非被刪除或將該消息放在隊列的最后,否則此循環將無限循環。

看一下刪除消息:到目前為止,如果我基於格式異常...那么我可能是錯的,因為將來我可能會遇到其他一些異常。

有沒有一種方法可以將這些消息放回列表中的最后一個隊列而不是隊列的開頭。

需要有關如何進一步進行操作的建議。

注意:Queue是Transactional。

據我所知,MSMQ不會自動將郵件轉儲到失敗隊列。 無論采用哪種方式,它都只有幾行代碼(Bill,Michael,我建議一個失敗隊列)。 就故障隊列而言,您可以簡單地創建一個名為.\\private$\\queuename_fail

在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);
}

如果發生錯誤,如果在web.config中為您的WCF服務配置了該消息,則該消息將被置於中毒隊列中。 另外,如果需要在一定延遲后重新處理郵件,則可以配置重試隊列。

更新:讓我解釋一下要求。 我們需要處理從其他系統發送來的少量xml,並且不得不將數據插入/更新/刪除到數據倉庫中。 有時,由於某些外部系統依賴性,更新請求會在創建請求之前被推送到隊列中。 因此,當拾取更新請求進行處理時,它會引發錯誤(因為該記錄在數據庫中不存在),然后將其推送到重試隊列中,等待5分鍾。 在此時間范圍內,如果拾取創建請求進行處理並成功,則在執行更新請求5分鍾后,它就成功了(因為現在它找到了要更新的匹配記錄)。 在本文中,說明了重試隊列和中毒隊列所需的配置更改。 除了在WCF服務中創建事務隊列和啟用事務之外,無需更改代碼。 使用WCF Net.Msmq綁定使用MSMQ進行毒葯和重試消息處理

暫無
暫無

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

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