【问题标题】:MSMQ via C# - ACK that message received?MSMQ 通过 C# - 确认收到的消息?
【发布时间】:2014-05-24 00:52:48
【问题描述】:

我正在通过 c# 向私有队列发送消息:

MessageQueue msgQ = new MessageQueue(@".\private$\aaa");
msgQ.Formatter = new XmlMessageFormatter(new[] { typeof (String) });
msgQ.Send(msg);

它确实有效,我确实看到了队列中的消息。

但是,有没有什么方法可以让消息进入队列是否成功?

ps

BeginPeekPeekCompleted 是一个事件,当消息在队列中可用或指定的时间间隔到期时引发。它没有帮助我,因为我需要知道 我发送的消息是否被 msmq 接收。 BeginPeek 也会在有人 else 向队列中输入消息时引发。我想要的最后一件事是通过BeginPeek 进行检查 - 此消息来自谁。

我该怎么做?

ps2

或者也许我不必担心,因为如果没有插入消息,msgQ.Send(msg); 会引发异常......?

【问题讨论】:

    标签: c# .net-4.5 msmq


    【解决方案1】:

    正如 Oleksii 解释的可靠交付。

    但这会影响性能。

    我可以建议的是:

    为什么不在将 MSG 发送到其他系统的机器上创建一个 MSMQ 服务器。

    我的想法是

    1. 服务器 1 向服务器 2 发送 MSMSQ
    2. 服务器 2 接收添加到队列中
    3. 服务器 2 处理队列/在此处触发您的代码以向服务器 1 发送 MSMQ 消息
    4. 服务器 1 接收 MSG(任何成功的带有 MSGId 的 msg)
    5. 做进一步的任务

    这种方法可能会加倍努力,但会使您的服务器远离性能滞后。

    【讨论】:

      【解决方案2】:

      我认为您尝试做的事情不应该在代码中处理。当您发送消息时,它被放置在传出队列中。它无法到达目的地的原因有很多,例如网络分区或目的地队列已满。但这对您的应用程序来说应该无关紧要 - 就它而言,它发送了消息,它提交了事务,它没有收到任何错误。其余的工作由底层基础架构负责,应监控该基础架构以确保没有技术问题。

      现在对您的应用程序真正重要的是交付保证。我从您所描述的场景中假设您需要持久的事务队列以确保消息不会丢失。有关可用选项的更多信息,请阅读here

      另外,如果您需要一些标识符作为确认显示给用户,通常的做法是在发送代码中生成它并将其放置在消息本身中。然后处理代码将使用 id 来完成所需的工作。

      【讨论】:

      • 我的 iis 和 msmq 计算机是同一台机器。如果是这样,消息在进入传入队列之前是否存储在传出队列中?此外,事务中完成的操作不超过 1 个……那么为什么不建议使用事务队列呢?
      • 好吧,正如我回答中的链接所指出的,如果队列处理服务在处理非事务性队列时崩溃,则当前消息会丢失。如果可以,请使用非事务性。至于另一个问题,如果所有通信都是本地的,则不应使用传出队列。
      【解决方案3】:

      使用事务队列并让您的所有计算机都注册 DTC 事务可能会满足您的需求。然而,这有点让人头疼,而且 DTC 有副作用——就像所有事务都一起注册,包括 DB 事务。

      也许更好的解决方案是使用 MassTransit 或 NServiceBus 之类的框架并执行请求-响应,允许收货人回复实际确认消息,不仅要说“这已交付”,还要说“我承认这一点”超时选项。

      【讨论】:

      • 不,我不是在找这个。我正在寻找代码来检查消息是否已正确插入队列。就这样。没有数据库。
      • 好吧,事务队列在事务关闭时确认进入队列。但是,如果队列是事务性的,那么当您读取它时,它也在事务范围内。哪个是您涉及 DTC 的地方。
      猜你喜欢
      • 1970-01-01
      • 2011-08-13
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 2021-12-21
      • 1970-01-01
      • 2011-01-18
      相关资源
      最近更新 更多