【发布时间】:2011-09-23 09:38:51
【问题描述】:
简介
我有一个基于 SEDA 的系统,并使用 MSMQ 在不同的应用程序/服务之间进行通信(事件触发)。
其中一个服务按文件获取消息,因此我有一个文件侦听器,它读取文件内容并将其插入队列(或实际上是 4 个不同的队列,但这对于第一个问题不是很重要)。
服务器是 Windows Server 2008
第一个问题 - 阅读速度变慢
我在另一端读取这些消息的应用程序通常每秒从队列中读取大约 20 条消息,但是当发布消息的服务开始排队数千条消息时,读取下降,读取应用程序只读取 2-每秒 4 条消息。当没有发布到队列时,读取应用程序每秒可以再次读取多达 20 条消息。
阅读应用程序的代码很简单,用C#开发,我使用System.Messaging中的Read(TimeSpan timeout)函数。
问:为什么当有大量消息发布到队列时读取速度变慢?
第二个问题 - TPS 的限制
另一个问题是关于阅读本身。如果我使用 1 或 5 个线程从队列中读取,我每秒可以读取多少条消息似乎没有区别。我还尝试实现“循环解决方案”,其中发布服务发布到一组随机的 4 个队列,并且读取应用程序有一个线程监听这些队列中的每一个,但即使我仍然只有 20 TPS从具有 1 个线程的 1 个队列、具有 4 个线程的 1 个队列或 4 个队列(每个队列一个线程)读取。
我知道线程中的处理大约需要 50 毫秒,所以如果当时只处理一条消息,则 20 TPS 是相当正确的,但多线程的线索应该是消息是并行处理的,而不是顺序处理的。
服务器上有大约 110 个不同的队列。
问:为什么即使使用多线程和使用多个队列,我一次也不能从队列中取出超过 20 条消息?
这是今天运行的代码:
// There are 4 BackgroundWorkers running this function
void bw_DoWork(object sender, DoWorkEventArgs e)
{
using(var mq = new MessageQueue(".\\content"))
{
mq.Formatter = new BinaryMessageFormatter();
// ShouldIRun is a bool set to false by OnStop()
while(ShouldIRun)
{
try
{
using(var msg = mq.Receive(new TimeSpan(0,0,2))
{
ProcessMessageBody(msg.Body); // This takes 50 ms to complete
}
}
catch(MessageQueueException mqe)
{
// This occurs every time TimeSpan in Receive() is reached
if(mqe.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
continue;
}
}
}
但是即使有4个线程,似乎都在等待函数再次进入“接收”点。我也尝试过使用 4 个不同的队列(content1、content2、content3 和 content4),但我仍然每 50 毫秒处理 1 条消息。
这与 Receive() 中的 TimeSpan 有什么关系,和/或是否可以省略它?
另一个问题是,如果使用私有队列,而不是公共队列可以解决什么问题?
【问题讨论】:
标签: c# .net msmq message-queue