Краткое введение
У меня есть система на основе SEDA, и я использовал MSMQ для связи (запуска событий) между различными приложениями / службами.
Одна из этих служб получает сообщения по файлам, поэтому у меня есть прослушиватель файлов, который считывает содержимое файла и вставляет его в очередь (или фактически в 4 разных очереди, но это не очень важно для первого вопроса).
Сервер - Windows Server 2008
Первый вопрос - замедление чтения
Мое приложение, которое читает эти сообщения на другой стороне, обычно читает около 20 сообщенийиз очереди в секунду, но когда служба, отправляющая сообщения, начинает ставить в очередь несколько тысяч сообщений, чтение прекращается, и приложение чтения читает только 2-4 сообщения в секунду.Когда нет сообщений в очереди, приложение чтения может снова читать до 20 сообщений в секунду.
Код в приложении для чтения довольно прост, разработан на C #, я использую функцию Read (TimeSpan timeout) в System.Messaging.
Q: Почему чтение замедляется, когдамного сообщений отправлено в очередь?
Второй вопрос - ограничения TPS
Дополнительный вопрос касается самого чтения.Кажется, нет разницы в том, сколько сообщений я могу прочитать в секунду, если я использую 1 или 5 потоков для чтения из очереди.Я также пытался реализовать «циклическое решение», при котором почтовый сервис отправляет в произвольный набор из 4 очередей, а приложение чтения имеет один поток, прослушивающий каждую из этих очередей, но все равно остается только 20 TPS, даже если ячтение из 1 очереди с 1 потоком, 1 очереди с 4 потоками или 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), но все равно я получаю 1 сообщение, обрабатываемое каждые 50 мс.
Имеет ли это какое-либо отношение к TimeSpan в Receive (), и / или возможно ли это пропустить?
Другой вопрос, если использование частных очередей вместо публичной волирешить что-нибудь?