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

Anúncios

2 comentários em “Integrações entre Sistemas – Parte 12 – MSMQ, Revisitado

    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

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s