Integrações entre Sistemas – Parte 12 – MSMQ, Revisitado

Objetivo

Na parte 7 dessa série vimos uma implementação baseada em MSMQ que ficou muito atrás da implementação em Websphere MQ e eu tinha me comprometido a revisá-la. O objetivo deste post é apresentar essa revisão.

A princípio imaginei que o resultado ruim estava relacionado a filas transacionais, mas na prática percebi que o problema estava principalmente relacionado ao tratamento do recebimento da fila de forma assíncrona.

Melhorias realizadas

Realizei algumas melhorias pequenas no código, substituindo o loop deselegante na thread principal por um ManualResetEvent e outras melhorias menores, mas o ponto chave estava no tratamento do evento “ReceiveCompleted” da fila.

Criei uma Queue e uma segunda thread para tratar de forma paralela, não obstruindo o caminho do MQ com código de processamento e deixando o canal de recepção de mensagens livre para dar mais vazão à fila de entrada. Ficou assim:


		private void inQueue_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
		{		
			
			lock (messageInputQueue)
			{
				messageInputQueue.Enqueue(e.Message);
				enqueueCount++;
				Log.LogMessage("Enqueued " + enqueueCount.ToString() + " messages");
			}
		
			if (enqueueCount < TotalBatches)
				inputQueue.BeginReceive();
		}

messageInputQueue trata-se da Queue a que me referi. É utilizado um “lock” para evitar concorrência entre a thread que empilha e a que desempilha as mensagens.

Este é o código que trata o processamento das mensagens, executado através de uma Task:

		private void ProcessInputQueue()
		{
			while (true)
			{
				Message msg = null;

				lock (messageInputQueue)
				{
					if (messageInputQueue.Count > 0)
						msg = messageInputQueue.Dequeue();
				}

				if (msg == null)
				{
					Thread.Sleep(50);
					continue;
				}
				
				StreamUtil.ImportarStream(ConnString, msg.BodyStream);
				Log.LogMessage("Processed message " + messageCount.ToString());					
				messageCount--;					

				if (messageCount <= 0)
					break;
			}
			processingDone.Set();
		}

Resultados

Abaixo segue os resultados completos inserindo também as execuções do MSMQ com filas transacionais e não-transacionais:

Integracoes-chart1

Integracoes-chart2

Como os resultados mostram, a diferença do Websphere MQ para o MSMQ não foi significativa, mas as diferenças entre a implementação anterior em MSMQ para a nova é absurdamente grande (praticamente o dobro!).

Código fonte

O código fonte completo está atualizado no Git Hub: https://github.com/ericlemes/IntegrationTests

Advertisements

2 thoughts on “Integrações entre Sistemas – Parte 12 – MSMQ, Revisitado

  1. Post muito bom, parabéns! Seria interessante um post semelhante utilizando WCF + ActiveMQ.

    Abraço.

    1. Cristian,

      Que bom que gostou. Vou colocar no meu roadmap, mas não prometo nada. Acho que o Rabbit MQ vem antes, depois algumas brincadeiras com Service Bus.

      Acho que vou botar um link de “donate” no blog pra ver se vem algum incentivo!

      Abraço,

      Eric

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s