MSMQ - 向事务队列发送消息变得非常缓慢

时间:2014-08-19 23:07:43

标签: c# performance .net-4.0 transactions msmq

我们有一个Intranet ASP.NET Web表单应用程序,它通过服务层执行实际工作,由.NET Remoting服务代表。几周前,我们已经开始从IIS获得超时异常,转而认为来自前端的请求未在允许的默认执行时间内处理(对于.NET 2.0+,它是110秒)。在调查期间,我们发现问题必须是将消息发送到事务性MSMQ队列(在W2K3 x64服​​务器上运行)。我们发送消息的方式如下:从DB我们得到我们想要推送到队列的所有记录,然后在 foreach 循环中按分开的MSMQ事务推送每条记录,如下所示: / p>

using (MessageQueue queue = new MessageQueue(@".\private$\OurQueue"))
{
  using (MessageQueueTransaction tran = new MessageQueueTransaction())
  {
    tran.Begin();
    Message msg = new Message(BODY); // BODY is some class which holds few fields of type Guid, String and DateTime 
    msg.Label = "Some label for the message";
    msg.UseDeadLetterQueue = true;
    msg.TimeToBeReceived = new TimeSpan(7, 0, 0, 0);
    msg.Priority = MessagePriority.Normal;
    queue.Send(msg, tran);
    tran.Commit();
    queue.Close();

    return msg.Id;
  }
}

要发送的消息数量可以达到30.000-100.000,这就是性能至关重要的原因。 使用秒表类进行的实验表明,如果您尝试更改逻辑并在一个事务中发送所有消息,如下所示:

using (MessageQueue queue = new MessageQueue(@".\private$\OurQueue"))
{
    using (MessageQueueTransaction tran = new MessageQueueTransaction())
    {
        tran.Begin();
        for (int i = 0; i < recordsNumber; i++)
        {
            Message msg = new Message(BODY); // BODY is some class which holds few fields of type Guid, String and DateTime 
            msg.Label = "Some label for the message";
            msg.UseDeadLetterQueue = true;
            msg.TimeToBeReceived = new TimeSpan(7, 0, 0, 0);
            msg.Priority = MessagePriority.Normal;
            queue.Send(msg, tran);
        }
        tran.Commit();
        queue.Close();
    }
}

性能要好得多 - 对于分离的事务,将30K的记录推送到MSMQ所需的时间是~115秒,而对于1个事务,它只需要~16秒。现在这一切都在猜测,因为分析和性能评估是在我的开发机器上完成的 - 我无法访问生产服务器,但这仍然让我想到:这是一个正确的比较,如果它是一个好的想法是在1次交易中向MSMQ发送数万条记录?然而,我仍然在寻找答案的主要问题是它是如何发生的,它是如此工作的最后一次7年左右的MSMQ交易分离,从未超时,但最近突然变得如此缓慢?除了从.NET 3.5迁移到4.0(不幸的是,因为我们仍在使用旧的W2K3服务器而不是4.5)我们没有更改代码中的任何内容和服务器管理员声称最近没有对服务器本身进行任何更改(DB x 1,使用Remoting x 2的服务,前端x 2)。我的开发机器上的分析表明,大部分工作似乎是在 queue.Send 中完成的,但它不应该导致代码超时,因为调用发送在设计上是异步的,即它应该立即返回给调用者(正如documentation中指出的那样)。向MSMQ发送消息的代码在“主”工作单元内运行,这是DB事务,但我怀疑MSMQ事务被提升到MSDTC - 我想在这种情况下它总是很慢。

有人知道我在这里想念的是什么吗?

0 个答案:

没有答案