Num ambiente de Microsserviços, dá para complicar um pouco mais a vida... quer dizer, melhorar a disponibilidade dos seus apps ASP.NET Core usando programação reativa, Event Sourcing e RabbitMQ. Porque, né, quem não gosta de um desafio extra logo de manhã?

cube white block lot on gray surface

Microsserviços

Microsserviços são um tipo de arquitetura. Eles permitem criar um app único como um conjunto de serviços pequenos e independentes que rodam, são desenvolvidos e implantados de forma isolada.

Resumindo, o estilo de arquitetura de microsserviços é criar um app único como um conjunto de pequenos serviços, cada um rodando no seu próprio processo e se comunicando de forma leve (…). Esses serviços são feitos em torno de capacidades de negócio e podem ser implantados de forma independente por meio de automação total, (…) podendo ser escritos em linguagens de programação diferentes e usando tecnologias de armazenamento de dados diferentes.

  • Martin Fowler

image

Event Sourcing

Event sourcing ajuda atualizar o estado de uma entidade e publicar eventos ao mesmo tempo. Sempre que o estado de um objeto muda, um novo evento é criado. Assim, dá para reproduzir o estado atual de uma entidade usando seus eventos.

Event Sourcing garante que todas as mudanças de estado de um aplicativo são guardadas como uma sequência de eventos. Podemos não só consultar esses eventos, mas também usar o registro de eventos para reconstruir estados antigos e ajustar o estado de forma automática para lidar com mudanças retroativas.

  • Martin Fowler

Por que usar Microsserviços e Event Sourcing juntos?

Porque juntar microsserviços e event sourcing traz um toque de mágica para criar sistemas com alta disponibilidade. Criar apps reativos é eficaz para usar melhor os recursos, aumentar a resposta e a disponibilidade do sistema geral. Eles reagem a estímulos ao invés de esperar por respostas tradicionais de request/response.

red theater curtain

Cenário

O clássico - Pedido encontra Pagamento. Dois serviços que juntos entregam um pagamento, sendo independentes, porque não gostamos de coisas fáceis demais:

image

  • Quando um pedido grita "Aqui!", o serviço Pedido emite um evento (PedidoEfetuadoEvent).
  • O serviço Pagamento, inscrito na fila PedidoEfetuadoEvent, recebe a mensagem e processa o pagamento.

image

MÃO NA MASSA

Agora, senhoras e senhores, vamos ver o EasyNetQ conectado ao RabbitMQ, com os eternos Background Services.

Código no GitHub

O projeto no GitHub usa um Frontend com ASP.NET Core MVC, um pouco diferente deste tutorial que usa uma Console Application para deixar tudo ainda mais emocionante.

Pré-requisitos

Para começar, você precisa do RabbitMQ. Use o RabbitMQ a partir do Docker.

docker run -d --hostname my-rabbit  --name rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3-management

Criando a solution

Crie uma Solution vazia chamada RabbitMQ-Example (Arquivo > Novo > Projeto > Outros Tipos de Projeto > Soluções do Visual Studio).

Nova solution

Domain

Este projeto tem as Models e Eventos que as APIs observam.

Adicione um projeto .NET Standard (Botão direito na Solução > Adicionar > Novo Projeto > .NET Standard > Biblioteca de Classes (.NET Standard)
newapi
domain

Adicione a referência do Newtonsoft.Json.

Altere o conteúdo da Class1:

// Código retirado do gist do autor

PedidoService

Adicione um novo projeto ASP.NET Core do tipo API chamado PedidoService (Botão direito na Solução > Adicionar > Novo Projeto > Aplicativo Web ASP.NET Core > API).

newapi
api

Adicione as seguintes referências do NuGet:

  • EasyNetQ
  • E a referência do projeto Domain.

Reference

Remova o arquivo ValuesController. Adicione outro controller chamado PedidoController.cs.

// Código retirado do gist do autor

PagamentoService - Background Service + Subscribe

Adicione um novo projeto à solução. (Botão direito na Solução > Adicionar > Novo Projeto > Aplicativo Web ASP.NET Core > API).

Apague o arquivo ValuesController (Controllers > ValuesController.cs).

Adicione as seguintes referências do NuGet:

  • EasyNetQ
  • CreditCardValidator
    Adicione uma nova pasta chamada BackgroundServices e crie uma classe NovoPedidoEventHandler.cs.
// Código retirado do gist do autor

Para registrar o Background Service, vá até o Startup.cs e altere o método ConfigureServices:

// Código retirado do gist do autor

Testando

Adicione ao projeto uma Console App chamada TesteApp (Arquivo > Novo > .NET Core > Console App (.NET Core)).

Adicione as seguintes referências do NuGet:

  • Refit

Adicione também a referência do Domain.

// Código retirado do gist do autor

Benefícios desta abordagem

O RabbitMQ garante que sua aplicação continue funcionando. Se o serviço de Pagamento resolver dar um tempo, as mensagens ficam seguras no RabbitMQ.

Veja o que acontece quando o serviço Pagamento está fora:

image

Download

Clippy Octocat

O projeto no GitHub usa um ASP.NET Razor MVC ao invés de uma Console Application. Confira no GitHub

Referências

E foi isso, seguimos juntos nesse caminho sem fim, com só mais um desafio na sua vida, onde o caos é o que realmente impulsiona a inovação.