【问题标题】:Cannot read remote private queue无法读取远程专用队列
【发布时间】:2012-05-28 14:22:47
【问题描述】:

我正在尝试让 MSMQ 5 在我的两台 Windows Server 2008 R2 虚拟机上运行。 我可以发送到本地和远程私有队列,我可以从本地私有队列中读取。 我无法从远程私有队列中读取数据。

我阅读了许多建议,尤其是 John Breakwell 在MSMQ Issue reading remote private queues (again) 总结的建议。

我已经做过的事情:

  • 关闭两台机器上的防火墙。
  • 确保Everyone 和AnonymousLogon 可以完全控制队列。 (如果我取消 AnonymousLogon 访问权限,那么我将无法远程发送到队列,并且消息在接收机器上以“访问被拒绝”结束。)
  • 两台机器上都允许未经身份验证的 Rpc。
  • 在两台机器上都允许 NewRemoteReadServerAllowNoneSecurityClient。

发送代码片段是:

        MessageQueue queue = new MessageQueue(queueName, false, false, QueueAccessMode.Send);
        Message msg = new Message("Blah");
        msg.UseDeadLetterQueue = true;
        msg.UseJournalQueue = true;
        queue.Send(msg, MessageQueueTransactionType.Automatic);
        queue.Close();

接收代码片段为:

   queueName = String.Format("FormatName:DIRECT=OS:{0}\\private$\\{1}",host,id);
   queue = new MessageQueue(queueName, QueueAccessMode.Receive);
   queue.ReceiveCompleted += new ReceiveCompletedEventHandler(receive);
   queue.BeginReceive();

...

    public void receive(object sender, ReceiveCompletedEventArgs e)
    {
        queue.EndReceive(e.AsyncResult);
        Console.WriteLine("Message received");
        queue.BeginReceive();
    }

我的 queueName 最终为 FormatName:DIRECT=OS:server2\private$\TestQueue

当我在队列中调用 beginReceive() 时,我得到

Exception: System.Messaging.MessageQueueException (0x80004005)
   at System.Messaging.MessageQueue.MQCacheableInfo.get_ReadHandle()
   at System.Messaging.MessageQueue.ReceiveAsync(TimeSpan timeout, CursorHandle cursorHandle, Int32 action, AsyncCallback callback, Object stateObject)
   at System.Messaging.MessageQueue.BeginReceive()

我在 Server1 上使用了 Wireshark 来查看网络流量。在不发布所有细节的情况下,它似乎经历了以下阶段。 (Server1 正在尝试从 Server2 上的队列中读取数据。)

  • Server1 与 Server2 联系,并且存在 NTLMSSP 质询/响应协商。一些回复提到“未知结果 (3),原因:超出本地限制”。
  • Server1 向 Server2 发送 rpc__mgmt_inq_princ_name 请求,Server2 回复相应的响应。
  • 有一些 ldap 交换查找域,然后引用 ldap://domain/cn=msmq,CN=Server2,CN=Computers,DC=domain 返回“无此类对象”响应。
  • 然后与 LDAP 服务器进行一些 SASL GSS-API 加密交换
  • 然后关闭到 ldap 服务器和 Server2 的连接。

我已尝试启用事件查看器 > 应用程序和服务日志 > Microsoft > Windows > MSMQ > End2End。它显示正在发送的消息,但没有说明尝试接收失败的原因。 我该如何进一步调试?

【问题讨论】:

    标签: msmq


    【解决方案1】:

    问题与域有关。 Server1 和 Server2 是开发域的一部分。我的登录帐户是公司域的一部分。开发域对公司域的信任足以让我登录、成为管理员成员、安装功能等。但读取远程队列似乎不够信任。

    我通过查看公共队列发现了这一点。如果我在读取远程 private 队列时遇到问题,也许我应该通过尝试 public 队列来获取更多数据。安装适当的目录集成功能后,我能够创建一个公共队列,但在公共队列列表中看不到它。试图刷新公共队列列表给了我这个错误:

    并非全部 可以显示公共队列。只有本地缓存​​的公共队列可以 显示。错误:在 Active Directory 中找不到对象。

    Google 向我指出了 John Breakwell 对类似问题 here 的回答,这表明信任关系不适用于消息传递协议。

    【讨论】:

    【解决方案2】:

    尝试改用标准 Receive 方法并指定事务类型,因为 BeginReceive 似乎不支持从事务队列接收。

    Message msg = queue.Receive(MessageQueueTransactionType.Automatic);
    

    MSMQ 并不总是返回逻辑错误消息...

    【讨论】:

    • Kjell-Åke,感谢您的建议。我很遗憾地报告它在与我之前的代码相同的 MQCacheableInfo.get_ReadHandle() 中以相同的 MessageQueueException 错误代码失败。它适用于从本地队列读取,但不适用于远程队列。 (我应该提到我的队列不是事务性的。)
    【解决方案3】:

    System.Messaging.MessageQueueException (0x80004005) 在 System.Messaging.MessageQueue.MQCacheableInfo.get_ReadHandle()

    这个错误也可能是由于 BeginReceive Read 在一个不存在的队列上引起的。检查配置以确保指定的队列路径物理存在并且具有“所有人”的完全权限

    【讨论】:

      猜你喜欢
      • 2011-10-22
      • 2023-03-24
      • 2021-04-26
      • 2012-12-01
      • 2011-04-16
      • 2015-01-20
      • 2015-04-02
      • 1970-01-01
      • 2013-06-22
      相关资源
      最近更新 更多