我正面临着一个非常令人费解的问题。我有一个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的消息。收到消息后,上述线程被唤醒并恢复其活动。
以下是整个架构的表示:
虽然所有操作都标有OneWay,但我想知道是否从另一个MSMQ操作中启动MSMQ操作在某种程度上是非法的。鉴于经验证据,似乎就是这种情况。如果是这样,是否可以改变这种行为?
编辑#2:
好吧,经过一番挖掘后,WCF似乎是罪魁祸首。我将MainService中的客户端代码和AuxService中的服务器代码都切换为直接使用MSMQ SDK,它按预期工作。我遇到的3分钟超时实际上是MainService放弃并认为AuxService失败的时间。因此,似乎由于某种原因,WCF拒绝执行发送,直到当前WCF活动退出。
这是设计还是错误?可以控制这种行为吗?
答案 0 :(得分:1)
您在队列代码上设置了事务,是否为事务设置了msmq对象? 3分钟听起来像分布式事务协调员登记的超时期限。