【问题标题】:Why are my queued WCF messages silently disappearing?为什么我排队的 WCF 消息会静默消失?
【发布时间】:2010-10-05 15:55:52
【问题描述】:

我在服务器 THOR 上设置了事务性 MSMQ 队列。我可以使用以下代码从工作站向该队列发布消息:

var queue = new MessageQueue("FormatName:Direct=OS:thor\\private\\myqueue");
using (var tx = new MessageQueueTransaction())
{
   tx.Begin();
   queue.Send("test", tx);
   tx.Commit();
}

但是,当我尝试使用 WCF 连接时,我的消息永远不会出现在队列中。这是我正在使用的配置:

<system.serviceModel>
  <bindings>
    <netMsmqBinding>
      <binding name="ClientNewsFeedServiceBinding" durable="true" exactlyOnce="true">
        <security mode="None" />
      </binding>
    </netMsmqBinding>
  </bindings>

  <client>
    <!-- NewsFeed Service -->
    <endpoint name="INewsFeedService"
              address="net.msmq://thor/private/myqueue"
              binding="netMsmqBinding"
              bindingConfiguration="ClientNewsFeedServiceBinding"
              contract="Service.Contract.INewsFeedService" />
  </client>
</system.serviceModel>

还有代码:

using (var tx = new TransactionScope())
{
   var cf = new ChannelFactory<INewsFeedService>("INewsFeedService");
   var service = cf.CreateChannel();
   service.TestMessage("test");
   ((IChannel)service).Close();
   tx.Complete();
}

我没有发现任何异常,但在 THOR 上的队列中没有发布任何消息。有任何想法吗?我什至不知道如何调试它,因为它只是默默地失败了。

更新

如果我将我的 MSMQ URI 更改为“net.msmq://localhost/private/myqueue”,那么它将发布到我设置的本地事务队列。队列本身的设置是相同的(例如,我执行了相同的步骤来创建 localhost 和 THOR 队列)。

【问题讨论】:

  • 这些消息是否出现在您的事务性死信队列中??
  • 不,事务 DLQ 中没有显示任何内容
  • 更新了我的答案 - 您检查过所有相关机器上的 DTC 吗??

标签: c# .net wcf msmq netmsmqbinding


【解决方案1】:

我相信如果您在 MSMQ 服务器端使您的队列具有事务性,您需要在 WCF 绑定配置中指定更多设置 - 试试这个:

<bindings>
    <netMsmqBinding>
      <binding name="ClientNewsFeedServiceBinding" 
               durable="true" exactlyOnce="true">
        <security mode="None" />
      </binding>
    </netMsmqBinding>
  </bindings>

如果我没记错的话,您需要将 durable="true"exactlyOnce="true" 属性添加到您的 netMsmq 绑定中才能正常工作。

有一个关于如何让 MSMQ 和 WCF 很好地协同工作的非常好的教程:

Tom 在第 3 部分中介绍了事务队列,并提到:

exactOnce="true" 属性是 WCF-speak 使用事务 消息队列。

durable=true 仅表示将消息立即刷新到磁盘,而不是将它们保存在服务器内存中。它速度较慢,但​​在服务器崩溃或电源中断的情况下,消息不会丢失。经典速度与可靠性的权衡......

更新:因为您要“跨越”机器边界,并且您正在使用事务队列 - 您是否检查了所有相关机器上的 DTC(分布式事务协调器)?查看 Tom 的博客第 3 部分:

检查 DTC 配置

我们史诗般的旅程即将结束。 事实上,如果你还在玩 在家里,您可以尝试运行 应用程序与事务 排队看它是否工作。 如果是 失败,一个可能的原因是 您的分布式问题 事务协调器配置。 以下是一些可以尝试的方法:

【讨论】:

  • 试过了,不行。我在原始帖子中添加了一个更新,说如果我将我的 MSMQ URI 更新为指向 localhost 而不是 THOR,我能够运行 WCF 代码。
【解决方案2】:

我遇到了同样的问题。在尝试了这里列出的所有想法后,我开始寻找其他东西。原来,当您选择安全模式时,我的消息的发件人属性为空(见下图)。

这样的消息在发送到localhost 时会被接受,但会被远程服务器拒绝。

为了让它发挥作用,你有几个选择:

  1. 启用身份验证
  2. 匿名登录授予发送权限

第一个选项当然更安全,但它需要与 Active Directory 集成一起安装 MSMQ。

【讨论】:

  • 不确定 WCF,但这解决了我在使用 NServiceBus 和 MSMQ 将消息发送到另一台机器并让它们静默丢弃时遇到的类似问题。将“匿名登录”权限添加到队列修复它(即使我已经拥有完全控制的“所有人”!)
【解决方案3】:

我有类似的问题,所以我希望这个清单有所帮助:

  1. 连通性:我想 thor DNS 条目正在工作,不是吗?检查它是否使 ping...
  2. 不同域的权限:我在一些 sprint 前遇到了问题,原因是权限。我的测试本地机器与服务器位于不同的域中。检查 thor 和你的机器是否在同一个域中。可以跨域使用它,但我无法让它工作(所以我将测试移到同一域中的机器上)
  3. 队列工具:虽然您可以从管理工具中看到队列,但我发现队列浏览器工具 (http://cogin.com/mq/index.php) 非常有用。您可以检查消息卡在哪里。

注意:可能 1 是可以的,但就我所说的情况而言......

【讨论】:

    【解决方案4】:

    您需要使用 MsmqIntegrationBinding。由于 WCF 不知道它们是什么,因此这些消息无法被识别并被丢弃。

    【讨论】:

    • 我认为 MsmqIntegrationBinding 是用于 WCF 应用程序和非 WCF 应用程序之间的互通。我手动向队列中添加内容的示例代码只是为了表明这不是一个简单的“关闭防火墙”问题。在生产中,队列只能由 WCF 服务访问。
    • 抱歉,我的眼睛被第二个客户跳过了。客户端是XP机器吗?我们在使用 XP 时遇到了 Kerberos 问题。有一个补丁。
    【解决方案5】:

    在关闭通道之前尝试完成事务范围。

    当您关闭通道时,您将与它失去联系,因此它有一个未提交的事务,最终被丢弃。

    【讨论】:

    • 那行不通。你说的有道理,但似乎没有什么不同。
    猜你喜欢
    • 2023-03-14
    • 1970-01-01
    • 2019-09-22
    • 1970-01-01
    • 1970-01-01
    • 2014-11-01
    • 2010-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多