已經列出MSMQ隊列中有毒郵件的一個奇怪問題。當檢測到中毒消息時,我使用下面的代碼來處理異常並將消息移動到毒性隊列中,但是由於即使從拋出的異常中獲取其lookupId,也找不到消息。請參閱以下相關代碼。未在隊列中找到MSMQ毒訊
public bool HandleError(Exception error)
{
var poisonException = error as MsmqPoisonMessageException;
if (null == poisonException) return false;
var lookupId = poisonException.MessageLookupId;
var queuePath = Environment.MachineName + "\\" + ConfigurationManager.AppSettings["QueuePath"];
var poisonQueuePath = Environment.MachineName + "\\" + ConfigurationManager.AppSettings["PoisonQueuePath"];
var orderQueue = new System.Messaging.MessageQueue(queuePath);
var poisonMessageQueue = new System.Messaging.MessageQueue(poisonQueuePath);
// Use a new transaction scope to remove the message from the main queue and add it to the poison queue.
using (var txScope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
int retryCount = 0;
while (retryCount < 3)
{
retryCount++;
try
{
// Try to get the poison message using the look up id. This line throws InvalidOperationException
var message = orderQueue.ReceiveByLookupId(lookupId);
// Send the message to the poison message queue.
poisonMessageQueue.Send(message, System.Messaging.MessageQueueTransactionType.Automatic);
txScope.Complete();
Logger.Debug("Moved poisoned message with look up id: " + lookupId + " to poison queue: " + ConfigurationManager.AppSettings["PoisonQueuePath"]);
break;
}
catch (InvalidOperationException e)
{
if (retryCount < 3)
{
Logger.Debug("Trying to move message to poison queue but message is not available, sleeping for 10 seconds before retrying", e);
Thread.Sleep(TimeSpan.FromSeconds(10));
}
else
{
Logger.Debug("Giving up on trying to move the message", e);
}
}
}
}
Logger.Info("Restarting the service to process rest of the messages in the queue");
WaitCallback restartCallback = new WaitCallback(Start);
ThreadPool.QueueUserWorkItem(restartCallback);
return true;
}
此代碼基本上從微軟的示例代碼here複製。
拋出的錯誤是正確的類型:
System.ServiceModel.MsmqPoisonMessageException: The transport channel detected a poison message.
但試圖從隊列中得到的消息時,我得到:
System.InvalidOperationException: Message requested was not found in the queue specified.
我首先想到的是,隊列可能沒有正確的權限設置,但我已經仔細檢查了網絡服務用戶具有讀寫消息到這兩個隊列的所有必要權限。
值得一提的是,這些代碼在生產中已經完美運行了數月,並且在過去許多有毒的消息中倖存下來。任何可能導致此問題的輸入都將不勝感激。
如果已經在督促工作了一段時間,就像你說的,我會看配置,而不是代碼。有沒有可能改變environment.machinename或appsettings.queuename?某種修補程序或錯誤配置的部署? – GregHNZ
@GregHNZ感謝您的輸入。配置是我檢查的第一件事情之一,隊列名稱和機器名稱都未更改。我們的託管服務提供商說,在我們開始發生問題的那一天沒有部署或補丁發生。 – cfj
發生此問題後,您是否繼續檢測到有毒消息?如果不是這樣,那麼毒害消息確實已經從隊列中消失了(例如,因爲要接收的時間已過期?)如果您確實繼續檢測到它,則表明LookupId可能不正確。無論採用哪種方式,您都可以將LookupId添加到您的catch塊內的Logger.Debug調用中。 –