7

我面临一个非常令人费解的问题。我有一个 Windows 服务,它监视两个 MSMQ 队列的输入并将消息发送到另一个 MSMQ 队列。尽管从服务的角度来看,发送操作似乎是即时的,但实际上消息恰好需要三 (3) 分钟才能到达(如 MSMQ MMC 中的属性窗口中所示)。我一直在测试这个问题,而另一边没有其他任何东西在听,这样我就可以看到消息堆积如山。这是服务发送消息的方式:

var proxyFactory = new ChannelFactory<IOtherServerInterface>(new NetMsmqBinding(NetMsmqSecurityMode.None)
{
    Durable = true,
    TimeToLive = new TimeSpan(1, 0, 0),
    ReceiveTimeout = TimeSpan.MaxValue
});

IOtherServerInterface server = this.proxyFactory.CreateChannel(new EndpointAddress("net.msmq://localhost/private/myqueue"));

var task = new MyTask() { ... };
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
    server.QueueFile(task);
    scope.Complete();
}

该服务在 Windows Server 2008 R2 上运行。我还在 R1 上对其进行了测试,并注意到了相同的行为。同样,一切都发生在同一台机器上。所有组件都部署在那里,所以我不认为这可能是网络问题。

编辑#1:

我打开了 WCF 诊断程序,我注意到很奇怪。MSMQ 数据报确实可以正常写入。但是,在“消息已关闭”跟踪消息之后,没有任何反应。就好像服务正在等待某事发生。恰好 3 分钟后,当 MSMQ 消息到达时(根据 MSMQ MMC),我看到另一条有关先前活动的跟踪消息。我怀疑有某种干扰。

让我为您提供有关服务如何运作的更多详细信息。有一个 IIS 应用程序从客户端接收任务并将它们放入 MSMQ 队列中。从那里,麻烦的服务(MainService)拿起它们并开始处理它们。在某些情况下,需要另一个服务 (AuxService) 来完成任务,因此 MainService 会向 AuxService 发送一条消息(总是延迟)。AuxService 有自己的收件箱队列,它在其中接收 MSMQ 消息,完成后,它会向 MainService 发送一条 MSMQ 消息。同时,向 AuxService 发送消息的线程一直等待,直到它收到信号或超时。MainService 有一个特殊的队列在其中查找来自 AuxServices 的消息。当收到消息时,上述线程被唤醒并恢复其活动。

这是整个架构的表示:

  • IIS 应用程序 -> Q1 -> MainService
  • MainService -> Q2 -> AuxService
  • 辅助服务 -> Q3 -> 主服务

尽管所有操作都标有 OneWay,但我想知道从另一个 MSMQ 操作中启动 MSMQ 操作是否在某种程度上是非法的。鉴于经验证据,情况似乎如此。如果是这样,是否可以改变这种行为?

编辑#2:

好吧,经过更多的挖掘,似乎 WCF 是罪魁祸首。我将 MainService 中的客户端代码和 AuxService 中的服务器代码切换为直接使用 MSMQ SDK,它按预期工作。我遇到的 3 分钟超时实际上是 MainService 放弃并认为 AuxService 失败的时间。因此,似乎出于某种原因,WCF 拒绝执行发送,直到当前 WCF 活动退出。

这是设计使然还是错误?这种行为可以控制吗?

4

1 回答 1

1

您在队列代码上设置了事务,是否设置了事务的 msmq 对象?3 分钟听起来像是分布式事务协调器登记的超时时间。

于 2013-09-19T02:57:05.103 回答