2

我正在尝试基于此架构(http://www.devx.com/enterprise/Article/39015)使用 MSMQ 实现可靠的 WCF 服务

如果队列不可用,则消息可能会丢失(即使集群不提供零停机时间)

看看简单的订单处理工作流程

  1. 用户输入信用卡详细信息并付款

  2. 应用程序从支付网关收到成功结果

  3. 应用程序通过 WCF MSMQ 绑定将消息作为“即发即弃”/“单向”调用发送到后端服务

  4. 用户将被重定向到“成功”页面

  5. 消息存储在远程事务队列中(Windows 集群)

  6. 后端服务出列并处理消息,完成复杂的订单处理工作流程,并因此向用户发送电子邮件确认

除了例外,一切看起来都很好。

我无法理解我们如何保证所有“单向”呼叫都将在队列中传递?双工通信不是一种情况,因为用户应尽快在结果网页上重定向。

想象一下这样的情况,当用户收到“成功”页面,其中的语言是“......您的付款已完成,订单已开始处理,您稍后将通过电子邮件发送通知......”但消息本身丢失了。

第 3 步如何实现持久性?

我可以看到的可能解决方案之一是

3a。创建一个带有标记为未完成的交易详细信息的数据库记录,以获取有关该交易的任何记录。该记录可以作为处理丢失消息的起点,以防消息不会保存在队列中。

我读了这篇文章

关于事务性 MSMQ,主要需要了解的是,在向远程队列的事务性发送中涉及三个不同的事务。

  1. 发送者将消息写入本地队列。
  2. 发送方机器上的队列管理器通过线路将消息传输到接收方机器上的队列管理器
  3. 接收者服务处理队列消息,然后从队列中删除消息。

但这并不能解决所描述的问题-据我所知,WCF netMsmqBinding 不使用本地队列将消息发送到远程队列。

4

1 回答 1

1

但这并不能解决所描述的问题-据我所知,WCF netMsmqBinding 不使用本地队列将消息发送到远程队列。

其实这是不正确的。无论您是否使用 WCF,MSMQ总是通过本地队列发送到远程队列。

如果您将消息发送到远程队列,然后查看服务器管理中的消息队列,您将在出站队列中看到已使用远程队列的地址创建了一个队列。这是一个自动为您创建的临时队列。如果远程队列由于某种原因不可用,则消息将位于本地队列中,直到可用,然后才被传输。

由于三阶段提交,因此提供了持久性:

  1. 在本地事务性地写入消息
  2. 事务性传输消息
  3. 事务性地接收和处理消息

在某些情况下,您可能会丢弃消息,例如,如果您的消息处理发生在出队事务范围之外,以及无法知道处理是否成功的情况(例如后端 Web 服务调用超时),当然你可能有一个格式错误的消息,它永远不会成功处理,但在所有情况下都应该可以为这些设计。

如果您在集群环境中使用公共队列,那么我认为可能会有更大的失败空间,因为集群 msmq 会引入复杂性(我没有真正使用过,所以我不知道)所以尽量避免。

于 2013-01-11T21:10:05.533 回答