繁体   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