检查 MSMQ 消息的状态和结果

Posted

技术标签:

【中文标题】检查 MSMQ 消息的状态和结果【英文标题】:Check the status and result of MSMQ message 【发布时间】:2014-09-03 12:15:16 【问题描述】:

我正在开发一个 RESTfull Web 服务,它执行以下操作:

    在 POST 请求时,它会启动一个长时间运行的任务。它为 MSMQ 排队消息,该消息在 Windows 服务托管应用程序中处理。它返回 HTTP 状态代码 202 Accepted 以及我们排队的作业的 ID。 客户端应用程序不断轮询服务(使用 GET),其 ID 为我们刚刚排队的作业。当 MSMQ 客户端完成任务后,它应该返回操作结果。如果不是,它将返回 202 Accepted 并带有适当的到期日期以进行下一次推荐的投票。

我的问题是:我应该如何实现从 MSMQ 到 Web 服务的通信?具体来说,我的 Web 服务如何知道消息是否由 MSMQ 客户端处理?

我的第一个想法是在 SQL 数据库中有一个“作业”表,其中包含一个 JobId、一个指示作业是否完成的标志和一个计算结果。然后,MSMQ 应用程序将在完成作业时写入此表,而 Web 服务将在每个请求上查询数据库以获取作业的状态。我不太喜欢这种方法,因为我的 Web 服务不会使用 SQL 服务器,否则工作的结果是幂等的(但很耗时),我不打算以任何方式保存它返回的数据。

我想知道是否有更惯用的方法来解决这个问题,因为这是我第一次处理 MSMQ 或一般的消息队列。

【问题讨论】:

您将需要某种持久存储来在 MSMQ 和 Web 服务之间进行通信。即使您对 MSMQ 消息处理器进行编码以使用结果回调 Web 服务,该服务仍然需要保留结果,以便在发出下一个请求时将它们返回给客户端应用程序。对我来说,使用数据库听起来是正确的方法。 【参考方案1】:

通过在您的流程中引入一个异步步骤,无论是否愿意,您都已经进入了eventual consistency 的领域。

这种方法存在固有的缺点,其中之一是如果调用者需要了解正在恢复的系统一致性,则必须不断检查收敛性。

这并不是说我不同意您的方法,但如果您使用的是普通 MSMQ,您需要了解这样做的后果。 MSMQ 本身并没有为您提供您期望从服务总线类型平台获得的任何消息交换语义,这将为您提供更多关于如何处理当前感知问题的选项。

例如,如果您可以通过 msmq(通过使用 NServiceBus 之类的东西)“回复”发件人,那么您可以使用某种服务器推送技术(例如 WebApi with SignalR)来实时提醒客户端,而无需持续到数据库。

另一种方法是放弃异步步骤,并用同步调用替换它,如果离线过程足够快地完成,这将是可行的。

但是,这些方法充其量是复杂的,我认为您当前的解决方案要简单得多。

【讨论】:

以上是关于检查 MSMQ 消息的状态和结果的主要内容,如果未能解决你的问题,请参考以下文章

MSMQ 消息队列错误处理

MSMQ BodyType 整数分配

消息队列MSMQ的使用

消息队列:celery

MSMQ消息队列的安装启用

如何并行处理 MSMQ 消息