5

我正在学习 NServiceBus 和 MSMQ。有人告诉我 MSMQ 中的事务队列很糟糕,使用它们对性能非常不利。有谁知道为什么?我猜这来自它使用 DTC 的概念,每个人都知道 DTC 并不是真正的可扩展解决方案。在我看来,带有 NServiceBus 的 MSMQ 并没有那么糟糕有几个原因,但我不知道我是否完全理解它是如何工作的。从逻辑上看,我可以想到 NServiceBus 可能使用事务来获得保证交付的 3 个地方:

  1. 通过网络发送消息时,您可能希望使用事务来确保消息在丢弃之前已到达远程队列。
  2. 从本地队列读取消息时,您可能希望确保在丢弃它之前成功处理它。
  3. 向多个订阅者发布消息时,您可能希望确保它在丢弃之前到达所有订阅者。(我真的希望这不是 NServiceBus 所做的)

谁能告诉我 NServiceBus 是如何做到这一点的?

4

3 回答 3

12

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

  1. 默认情况下,MSMQ 仅保证您的本地 msmq 基础结构已收到消息。不要求接收服务器在线。不过可以启用此功能(请参阅下面 John 的回答)

  2. 这是 IMO NSB 的主要卖点之一。使用跨越本地队列和数据存储的事务(即分布式事务)的能力对于保证一致性至关重要。即,如果某事失败,则不会在您的数据存储中保留任何内容,并且消息会回滚并重试,而用户无需执行任何操作。

  3. 与#1 相同。唯一的保证是每个订阅者最终都会收到发布的消息。只要您有可用的磁盘空间并且发布服务器调用将立即返回,就不会进行阻塞调用。

希望这可以帮助!

于 2010-08-18T20:42:39.837 回答
1

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

于 2010-08-18T20:19:44.180 回答
0

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

于 2010-09-02T12:19:49.787 回答