【问题标题】:Routing MSMQ messages from one queue to another将 MSMQ 消息从一个队列路由到另一个队列
【发布时间】:2012-02-06 09:35:48
【问题描述】:

是否有一些标准配置设置、服务或工具可以接受来自一个队列的消息并将它们移动到另一个队列?自动处理死消息问题,并提供一些重试能力?我在想这就是“MSMQ 消息路由”所做的,但似乎找不到关于它的文档(Windows Mobile 6 除外,我不知道这是否相关)。

上下文:

我知道,在使用 MSMQ 时,您应该始终写入本地队列,这样就不太可能发生故障,然后 X 应该将该消息移动到远程队列。我的理解错了吗?这就是像 Biztalk 这样的消息传递基础设施的用武之地吗?是否不需要先写入本地队列以绝对确保成功?我应该自己构建 X 吗?

【问题讨论】:

标签: msmq biztalk


【解决方案1】:

正如 Hugh 所指出的,您只需要一个 MSMQ 队列就可以将消息从一个方向发送到一个目标。源和目标可以在同一台服务器、同一网络或跨互联网,但是,源和目标都必须运行 MSMQ 服务。

如果您需要进行“消息”路由(例如,处理来自多个源或目标队列的消息的交换机,或者根据消息类型将消息路由到一个或多个订阅者等),您需要的不仅仅是 MSMQ队列。 虽然您当然可以使用 BizTalk 进行消息路由,但如果您不需要使用 BizTalk 的其他功能,这将是昂贵的/过大的。建议你看看开源,或者自己构建一些自定义的东西。

但是通过“路由”,您可能指的是使用 HTTP 作为传输时的队列重定向功能,例如通过互联网(例如 herehere)。

Re : 发送失败并重试

我认为您已经掌握了大部分概念 - 通常消息传递重试功能应该隐含在 MSMQ 中。如果 MSMQ 无法在定义的过期时间之前传递消息,那么它将在死信队列中返回,然后源可以处理来自 DLQ 的消息,然后对它们进行“补偿”(例如,反转“发送”的操作,向用户指示失败等)。

但是,目标应用程序/侦听器需要执行目标中的“处理”类型重试(例如,如果目标系统关闭、死锁等)

执行此操作的常用方法包括:

  • 使用 2 阶段提交 - 在分布式工作单元下,将消息从 MSMQ 中拉出并进行处理(例如,将数据插入数据库,更改某些记录的状态等),如果遇到任何故障,则离开消息回到队列中,数据库更改将被回滚。
  • 应用程序级别重试 - 即在目标系统上,如果发生“可重试”类型错误(由于负载、死锁等而导致超时),然后休眠几秒钟,然后重试相同的事务。

但是,在大多数情况下,不希望无限期地重试处理,您最终需要承认失败并实施一种机制来记录消息和错误并将其从队列中删除。

但我不会“重试”业务失败(例如业务规则、验证等),并且应该在您的要求中定义如何处理这些问题的行为(例如帐户透支、消息格式不正确或不正确)有效等),例如通过将“NACK”类型的消息返回给源。

HTH

【讨论】:

  • 谢谢nonnb!阅读您的建议后,我最终找到了 BizTalk 的更轻量级的替代品,如 NServiceBus 和 Mass Transit,但更重要的是找出哪些层 不是必需的,现在我们可以简单地通过 VPN 链接传递 msmq 消息到远程系统,而不是拥有所有的中间层。
  • 出于兴趣,您可能还想查看基于 AMQP 的队列,例如 RabbitMQ 和 Azure Service Bus。在 Rabbit 中,exchange 只需配置即可将消息路由到另一个 exchange,不需要额外的代码。
【解决方案2】:

MSMQ 将消息从一个队列发送到另一个队列。

假设您在远程机器上有一个队列。您想向该队列发送消息。

所以你创建了一个发件人。发件人是可以使用 MSMQ 传输来发送消息的应用程序。这可以是 .Net 队列客户端 (System.Messaging)、WCF 服务使用者(通过 netMsmqBinding 或 msmqIntegrationBinding、使用 MSMQ 适配器的 BizTalk 等。

当你发送消息时,实际发生的是:

  1. 发件人计算机上的 MSMQ 队列管理器将消息写入临时本地队列。
  2. 发送方机器上的 MSMQ 队列管理器连接到接收机器上的 MSMQ 管理器并传输消息。
  3. 接收方计算机上的 MSMQ 队列管理器将消息放入目标队列。

在某些情况下,MSMQ 会遇到由于某种原因无法在目标队列上接收的消息。在这些情况下,如果您已指示消息将使用死信队列,那么 MSMQ 将确保将消息转发到死信队列。

【讨论】:

  • 这对我很有用。对于任何试图理解这个问题的人来说,更多信息是,经过一些测试,我发现计算机管理 |服务和应用 |消息队列 |传出队列是查找消息在传递之前所在位置的正确位置。
  • @tom 虽然是对 MSMQ 的合理描述,但它没有回答 OP 的“将 MSMQ 消息从一个队列路由到另一个队列”的问题。点对点传输不是路由。
  • 同意 - @khanfx 请将我的帖子取消标记为答案并奖励给另一个答案。
猜你喜欢
  • 2012-04-29
  • 2020-07-12
  • 2014-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多