0

我有一个 MSMQ 应用程序设置,其中数据被推送到一个队列中。最初我只有一个进程从中读取并处理它。由于体积增加了,我启动了多个进程来读取它,这基本上是我原始进程的一个新实例。我没有看到任何错误,但性能确实下降了。我的理解是,每个进程都会从队列中读取并接收尚未处理的新消息并继续处理。这是正确的还是多个进程可能最终处理相同的消息?

    Dim q As MessageQueue
    If MessageQueue.Exists(".\private$\MsgsIQueue") Then
        q = New MessageQueue(".\private$\MsgsIQueue")
    Else
        'GS - If there is no queue then we're done here
        Console.WriteLine("Queue has not been created!")
        Return
    End If

     While True
            Dim message As Message
            counter += 1
           Try
                If q.Transactional = True Then
                    Thread.Sleep(2000)
                End If
                q.MessageReadPropertyFilter.ArrivedTime = True
                message = q.Peek(TimeSpan.FromSeconds(20.0))
                message.UseJournalQueue = True
                message = q.Receive(New TimeSpan(0, 0, 60))
                message.Formatter = New XmlMessageFormatter
                                   (New [String]() {"System.String"})
                ProcessMessage(message)
                ....
4

1 回答 1

2

好的,您确定实际上是队列读取导致了性能下降吗?我怀疑您的管道中还有其他一些瓶颈,因为 MSMQ 非常擅长处理来自多个进程/线程的读取。

如果我看一下您的代码,我会建议进行以下更改:

  • 如果是 tx 队列,为什么要休眠 2 秒?如果队列为空,请始终使用 tx 队列并将对 Sleep 的调用移至 catch 块以等待间隔。

  • 将过滤器的设置移到循环之外。

  • 删除对 Peek 的调用,因为它没有任何价值。

  • 使用日志队列仅在发送消息时使用。所以删除它。

  • 而是在队列上设置格式化程序,它将用于所有读取。

您还应该将对 Read 和 ProcessMessage 的调用包装在 TransactionScope 中,您还将 ProcessMessage 包装在另一个 try/catch 块中。这样,如果 ProcessMessage 中一切正常,您就可以提交读取,或者选择中止读取或将消息移动到死信队列。

于 2013-02-12T23:14:27.497 回答