【问题标题】:Handling poison messages in MSMQ在 MSMQ 中处理有害消息
【发布时间】:2016-05-04 17:29:59
【问题描述】:

当前设置包括一个 windows 服务,它从本地队列中提取消息并提取信息并放入我的 SQL 数据库。根据我的设计

  1. 服务从队列中提取消息。(我在这里使用 Peek())。
  2. 将其发送到数据库。
  3. 如果由于某种原因我在将其保存到数据库时遇到异常,则消息将返回到队列中,这对我来说是可靠的。
  4. 我正在记录错误,以便用户了解问题所在并进行修复。

异常示例:如果在将消息保存到数据库的过程中 DBconnection 丢失,则消息不会丢失,因为它们在队列中。我不会提交,直到我从 DB 确认消息是插入。因此用户可以查看日志并确保 DBconnection 存在并且一切正常,并且我们不会丢失队列中的任何消息。

但是考虑另一种情况:我将在队列中收到的消息来自根据标准架构的第 3 方。架构将保持不变,并且没有任何变化。但我已经看到了一些我得到一些的地方格式异常,并且由于未提交消息,因此该消息将返回队列。此时,该消息对我来说将是一个瓶颈,因为再次拾取相同的消息并尝试处理该消息。每次服务都会拾取相同的消息并得到相同的异常。因此,除非该消息被删除或将该消息放在队列的最后,否则此循环将无限循环。

正在考虑删除消息:截至目前,如果我基于格式异常...那么我可能是错的,因为我将来可能会遇到其他一些异常。

有没有办法我可以将此消息放回队列中列表的最后而不是队列的开头。

需要一些关于如何进一步进行的建议。

注意:队列是事务性的。

【问题讨论】:

  • 如果错误需要人工干预,您不会将它们移至第二个错误队列吗?
  • 我必须和@Bill 一起去,就是这样。将分解的消息移动到它们自己的队列中,以便对其进行管理。我们每天处理数十万条 MQ 消息,这是唯一可管理的方法。这使得 PROD 队列运行并处理它所能做的。然后,当这些队列收到消息时,我们使用 Patrol 来提醒我们。
  • @bill 是否有一个 MSMQ 功能可以将这些消息放入故障转移或备份队列......或者应该在代码上完成。
  • 我的回答是基于排队的基本知识,而不是专门针对 MSMQ - 这就是我发表评论的原因。如果有人可以在下面给出更详细和具体的答案,我很高兴他们能够获得声誉积分。

标签: c# sql msmq


【解决方案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);
}

【讨论】:

  • 感谢您提供的示例,但是如果 _failQueue 会受到严重影响并且会导致另一个问题,或者有人必须手动清除这些消息怎么办。或者将它保存到文件而不是队列是个好主意。
  • 这取决于你想要什么。您可以手动清理它,您可以让另一个进程监视它并对其进行处理(即可能继续尝试处理它),或者您可以将其转储到文件中。你必须决定在那里做什么。
  • 我宁愿使用文件,因为它易于维护,并且与 msmq 不同,我可以看到消息的实际内容,并且我可以使用您的代码来测试至少如何移动到队列的末尾.
猜你喜欢
  • 1970-01-01
  • 2012-04-12
  • 1970-01-01
  • 2017-02-12
  • 1970-01-01
  • 2012-07-24
  • 2011-07-27
  • 1970-01-01
  • 2010-12-26
相关资源
最近更新 更多