Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Dica
Esse conteúdo é um trecho do eBook, arquitetura de microsserviços do .NET para aplicativos .NET em contêineres, disponível em do .NET Docs ou como um PDF para download gratuito que pode ser lido offline.
Devemos começar dizendo que, se você criar seu barramento de eventos personalizado com base no RabbitMQ em execução em um contêiner, como o aplicativo eShopOnContainers faz, ele deve ser usado apenas para seus ambientes de desenvolvimento e teste. Não o use para seu ambiente de produção, a menos que você o esteja criando como parte de um barramento de serviço pronto para produção, conforme descrito na seção Recursos adicionais abaixo. Um barramento de eventos personalizado simples talvez não tenha muitos recursos críticos prontos para produção que um barramento de serviço comercial tem.
Uma das implementações personalizadas do barramento de eventos no eShopOnContainers é, basicamente, uma biblioteca que utiliza a API RabbitMQ. (Há outra implementação baseada no Barramento de Serviço do Azure.)
A implementação do barramento de eventos com o RabbitMQ permite que os microsserviços assinem eventos, publiquem eventos e recebam eventos, conforme mostrado na Figura 6-21.
Figura 6-21. Implementação de um barramento de eventos do RabbitMQ
O RabbitMQ funciona como um intermediário entre o editor de mensagens e os assinantes, para lidar com a distribuição. No código, a classe EventBusRabbitMQ implementa a interface IEventBus genérica. Esta implementação é baseada na Injeção de Dependência, permitindo que você troque desta versão de desenvolvimento/teste para uma versão de produção.
public class EventBusRabbitMQ : IEventBus, IDisposable
{
// Implementation using RabbitMQ API
//...
}
A implementação do RabbitMQ de um barramento de eventos de Desenvolvimento/Teste de exemplo é um código clichê. O sistema deve gerenciar a conexão com o servidor RabbitMQ e fornecer o código necessário para publicar um evento de mensagem nas filas. Ele também precisa implementar um dicionário de coleções de manipuladores de eventos de integração para cada tipo de evento; esses tipos de evento podem ter uma instância diferente e assinaturas diferentes para cada microsserviço receptor, conforme mostrado na Figura 6-21.
Implementando um método de publicação simples com RabbitMQ
O código a seguir é uma versão simplificada de uma implementação de barramento de eventos para RabbitMQ, para mostrar todo o cenário. Na prática, a conexão não é tratada dessa maneira. Para ver a implementação completa, consulte o código real no repositório dotnet-architecture/eShopOnContainers .
public class EventBusRabbitMQ : IEventBus, IDisposable
{
// Member objects and other methods ...
// ...
public void Publish(IntegrationEvent @event)
{
var eventName = @event.GetType().Name;
var factory = new ConnectionFactory() { HostName = _connectionString };
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
channel.ExchangeDeclare(exchange: _brokerName,
type: "direct");
string message = JsonConvert.SerializeObject(@event);
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(exchange: _brokerName,
routingKey: eventName,
basicProperties: null,
body: body);
}
}
}
O código real do método Publish no aplicativo eShopOnContainers é aprimorado usando uma política de repetição Polly, que repetirá a tarefa algumas vezes se o contêiner do RabbitMQ não estiver pronto. Esse cenário pode ocorrer quando o docker-compose está iniciando os contêineres; por exemplo, o contêiner RabbitMQ pode começar mais lentamente do que os outros contêineres.
Conforme mencionado anteriormente, há muitas configurações possíveis no RabbitMQ, portanto, esse código deve ser usado apenas para ambientes de desenvolvimento/teste.
Implementando o código de assinatura com a API RabbitMQ
Assim como acontece com o código de publicação, o código a seguir é uma simplificação de parte da implementação do barramento de eventos para RabbitMQ. Novamente, você geralmente não precisa alterá-lo, a menos que você deseje melhorar.
public class EventBusRabbitMQ : IEventBus, IDisposable
{
// Member objects and other methods ...
// ...
public void Subscribe<T, TH>()
where T : IntegrationEvent
where TH : IIntegrationEventHandler<T>
{
var eventName = _subsManager.GetEventKey<T>();
var containsKey = _subsManager.HasSubscriptionsForEvent(eventName);
if (!containsKey)
{
if (!_persistentConnection.IsConnected)
{
_persistentConnection.TryConnect();
}
using (var channel = _persistentConnection.CreateModel())
{
channel.QueueBind(queue: _queueName,
exchange: BROKER_NAME,
routingKey: eventName);
}
}
_subsManager.AddSubscription<T, TH>();
}
}
Cada tipo de evento tem um canal relacionado para obter eventos do RabbitMQ. Em seguida, você pode ter quantos manipuladores de eventos por canal e tipo de evento forem necessários.
O método Subscribe aceita um objeto IIntegrationEventHandler, semelhante a uma função de callback no microsserviço atual, juntamente com o objeto IntegrationEvent correspondente. Em seguida, o código adiciona esse manipulador de eventos à lista de manipuladores de eventos que cada tipo de evento de integração pode ter por microsserviço do cliente. Se o código do cliente ainda não estiver registrado no evento, ele criará um canal para o tipo de evento, permitindo que receba eventos de maneira push do RabbitMQ quando esse evento for publicado por qualquer outro serviço.
Conforme mencionado acima, o barramento de eventos implementado no eShopOnContainers tem apenas uma finalidade educacional, pois trata apenas dos cenários principais, portanto, não está pronto para produção.
Para cenários de produção, verifique os recursos adicionais abaixo, específicos para RabbitMQ e a seção Implementando comunicação baseada em eventos entre microsserviços .
Recursos adicionais
Uma solução pronta para produção com suporte para RabbitMQ.
Conexão Peregrine – Simplificar sua integração com design, implantação e gerenciamento eficientes de aplicativos, APIs e fluxos de trabalho
https://www.peregrineconnect.com/why-peregrine/rabbitmq-integrationNServiceBus – barramento de serviço comercial com suporte completo com ferramentas avançadas de gerenciamento e monitoramento para .NET
https://particular.net/EasyNetQ – Cliente de API .NET de software livre para RabbitMQ
https://easynetq.com/MassTransit – Estrutura de aplicativo distribuída gratuita e de software livre para .NET
https://masstransit-project.com/Rebus – Barramento de Serviço .NET de código aberto
https://github.com/rebus-org/Rebus