2010-08-18 73 views
5

我正在学习NServiceBus和MSMQ。有人告诉我,MSMQ中的事务队列是不良的,使用它们对性能来说真的很糟糕。有谁知道为什么?我猜测这是来自它使用DTC的概念,并且每个人都知道DTC并非真正的可扩展解决方案。在我看来,MSMQ和NServiceBus并不是那么糟糕,但我不知道我是否理解它是如何工作的。在此寻找逻辑,我能想到的3个地方NServiceBus可能为了利用交易得到保证传输:NServiceBus:不是MSMQ事务BAD?

  1. 当发送跨网络的消息,你可能想使用事务,以确保消息有在丢弃之前已经到达远程队列。
  2. 从本地队列中读取消息时,可能需要确保在丢弃消息之前处理成功。
  3. 向多个订阅者发布消息时,可能需要确保在放弃消息之前将其发送到所有消息。 (我真的希望这不是什么NServiceBus)

任何人都可以设置我直接如何NServiceBus做到这一点?

+1

他们可能是一个有点性能挑战 - 但我不会称他们为坏 - 具有交易的操作通常是“好事”(TM) – 2010-08-18 18:29:24

+0

发送事务性MSMQ消息不使用DTC。 虽然发送事务性MSMQ消息并将事实写入SQL服务器(作为示例)将使用DTC。 – 2010-09-02 12:22:49

回答

12

Msmq事务并不保证接收方已收到该消息。该事务保证消息已被您的机器上的msmq基础设施接收到,并且如果消息是持久的(NSB中的默认值),这意味着它已被保留在磁盘上并且在重新启动后仍然存在。该消息将通过msmq传递而不会阻塞调用者。这更好地称为“存储和转发”

  1. 默认情况下,MSMQ只保证您的本地msmq基础结构已收到消息。不要求接收服务器在线。这可以通过启用(见John的答案)

  2. 这是国际海事组织的关键卖点之一。使用跨本地队列和数据存储的事务(即分布式事务)的能力对于保证一致性至关重要。也就是说,如果某件事失败,则数据存储中不会存留任何东西,并且消息将被回滚并重试,而用户不必执行任何操作。

  3. 与#1相同。唯一的保证是每个用户最终都会收到发布的消息。没有阻塞呼叫,只要你有可用的磁盘空间和发布服务器,呼叫将立即返回。

希望这有助于!

1

点#2是正确的。你不想要一条消息导致错误,然后通过裂缝。您希望消息处理程序成功,在这种情况下,它会从队列中删除,或者失败并回滚,以便在可达到可配置的重试次数后重试或发送到错误队列进行分析。

0

第1点 - 不完整。如果您使用带有死信队列和TTRQ/TTBR定时器的负面和正面源日志记录,事务性消息会为您提供此信息。然后,您可以确切地确定消息发生了什么 - 如果它被拒绝,是否已发送,是否已处理。