Fala Galera,
Hoje venho falar sobre como podemos desacoplar nossa aplicação, distribuindo o processamento de alguns serviços e ganhando escalabilidade. Esse paradigma em computação é conhecida como Computação Distribuída. Um dos conceito da computação distribuída é a troca de mensagem com a utilização de Filas. E neste post estarei demonstrando como usar uma topologia de fila com o RabbitMQ
O que é RabbitMQ Message Broker?
RabbitMQ é uma serviço de Message Broker, open source multiplataforma que foi desenvolvido em ERLANG, totalmente suportados por diversas linguagens de programação, fácil de usar, confiável, com administração nativa e failover.
Instalação
Para essa demostração, irei utilizar o Linux Ubuntu 14.04 LTS, nele estará instalado toda infraestrutura necessária
Vamos usar o APT-GET Repository para instalar o RabbitMQ, execute os comandos abaixos no terminal
Adicionar a entrada do RabbitMQ no source do ATP-GET
echo 'deb http://www.rabbitmq.com/debian/ testing main' | sudo tee /etc/apt/sources.list.d/rabbitmq.list
Adicionar a chave pública
wget -O- https://www.rabbitmq.com/rabbitmq-release-signing-key.asc | sudo apt-key add -
Atualizar os pacotes
sudo apt-get update
Instalar o Message Broker
sudo apt-get install rabbitmq-server
Habilitando o Painel de Administração
Vamos habilita o seu painel de Administração assim ficará fácil de administrar os usuários, ver as filas e quantas mensagem cada fila tem.
Execute o comando abaixo para habilitar o Painel de Administração
rabbitmq-plugins enable rabbitmq_management
Com o comando executar, o painel de administração ficar acessível através da seguinte URL http://<servername>:15672. Para acessar o RabbitMQ cria um usuário para com o username guest e senha guest abaixo a imagem da página inicial do painel administrativo
Dica: O usuário “guest” somente tem acesso ao painel de administração localmente caso esteja usando uma maquina virtual, crie um novo usuário através da aba Admin
Topologias
O RabbitMQ suporta diversas topologias que podemos usar para escalonar nosso processamos vou enumerar algumas suportadas
Topologia Simples — Consiste e um publisher e um consumer. Neste cenário o publisher envia uma mensagem para fila e o consumer recebe a mensagem da fila e realiza o processamento
Topologia Worker- Consiste e um publisher e em um ou mais consumer. Neste cenário o publisher envia uma mensagem para fila e o RabbitMQ envia para o consumer que estiver disponível assim podemos escalar e colocar quantos consumer forem necessário. para realizar o processamento das mensagens. A fila do RabbitMQ é atômica ou seja, apenas um item da fila é obtido por vez, não há riscos de mais de um consumer obter a mesma mensagem.
Publish/Subscriber: Consiste em fazer copia da mesma mensagem para uma ou mais filas que assinam esta mensagem e que contém um ou mais consumer. Para a copia de mensagem utilizaremos um fila chamada Exchange (fanout).
Aplicação de Exemplo em C#
Com o entendimento das topologias, vamos criar uma aplicação de exemplo que irá publicar uma mensagem na fila através do publisher e consumir esta mensagem através de um consumer
Vamos criar dois Console Applications, um será o responsável por enviar a mensagem para a fila e outra será o responsável por ler a mensagem da fila
Para utilizar os recursos da fila devemos instalar o pacote do RabbitMQ.Client através do NuGet Package. Execute o comando Install-Package RabbitMQ.Client no Package Manager Console no Visual Studio
Publisher:
[code langugae=”csharp”]
namespace Publisher
{
class Program
{
static void Main(string[] args)
{
string hostName = “192.168.8.194”;
string userName = “sys”;
string password = “123456”;
string queueName = “Message-Queue”;
//Cria a conexão com o RabbitMq
var factory = new ConnectionFactory()
{
HostName = hostName,
UserName = userName,
Password = password,
};
//Cria a conexão
IConnection connection = factory.CreateConnection();
//cria a canal de comunicação com a rabbit mq
IModel channel = connection.CreateModel();
//Cria a fila caso não exista
channel.QueueDeclare(queue: queueName, durable: true, exclusive: false, autoDelete: false, arguments: null);
for (int i = 1; i <= 500; i++)
{
String mensagem = $”Enviando a mensagem {i}”;
byte[] body = Encoding.Default.GetBytes(mensagem);
//Seta a mensagem como persistente
IBasicProperties properties = channel.CreateBasicProperties();
properties.Persistent = true;
//Envia a mensagem para fila
channel.BasicPublish(exchange: String.Empty, routingKey: queueName, basicProperties: properties, body:body);
}
Console.WriteLine(“Mensagem enviadas para fila”);
Console.Read();
}
}
}
[/code]
Ao executar o programa do publisher ele envia as mensagem para a fila conforme a imagem abaixo:
Consumer:
[code language=”csharp”]
namespace Consumer
{
class Program
{
static void Main(string[] args)
{
string hostName = “192.168.8.194”;
string userName = “sys”;
string password = “123456”;
string queueName = “Message-Queue”;
const int NUMBER_OF_WORKROLES = 3;
//Cria a conexão com o RabbitMq
var factory = new ConnectionFactory()
{
HostName = hostName,
UserName = userName,
Password = password,
};
//Cria a conexão
IConnection connection = factory.CreateConnection();
//cria a canal de comunicação com a rabbit mq
IModel channel = connection.CreateModel();
for (int i = 0; i < NUMBER_OF_WORKROLES; i++)
{
Task.Factory.StartNew(() =>
{
lock (channel)
{
var consumer = new EventingBasicConsumer(channel);
consumer.ConsumerTag = Guid.NewGuid().ToString(); // Tag de identificação do consumidor no RabbitMQ
consumer.Received += (sender, ea) =>
{
var body = ea.Body;
var brokerMessage = Encoding.Default.GetString(ea.Body);
Console.WriteLine($”Mensagem recebida com o valor: {brokerMessage}”);
//Diz ao RabbitMQ que a mensagem foi lida com sucesso pelo consumidor
channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: true);
};
//Registra os consumidor no RabbitMQ
channel.BasicConsume(queueName, noAck: false, consumer: consumer);
}
});
}
Console.Read();
}
}
}
[/code]
Ao executar o programa consumer conseguiremos ler as mensagens da fila conforme figura abaixo:
O RabbitMQ é um produto muito poderoso e flexível. Neste post vimos algumas características de funcionamento porém existem outras características que o torna ele uma produto fantástico. Com o RabbitMQ podemos desacoplar fluxos de programação garantindo assim escalabilidade e performance.
Para saber mais sobre o RabbitMQ clique aqui
O código deste post pode ser encontrado no meu GitHub através deste link
Abs e até a próxima