Comunicação assíncrona baseada em mensagensAsynchronous message-based communication

Mensagens assíncronas e comunicação controlada por evento são críticos ao propagar alterações entre vários microsserviços e seus modelos de domínio relacionados.Asynchronous messaging and event-driven communication are critical when propagating changes across multiple microservices and their related domain models. Conforme mencionado anteriormente na discussão, microsserviços e BCs (Contextos Limitados), modelos (Usuário, Cliente, Produto, Conta etc.) podem ter diferentes significados para diferentes microsserviços ou BCs.As mentioned earlier in the discussion microservices and Bounded Contexts (BCs), models (User, Customer, Product, Account, etc.) can mean different things to different microservices or BCs. Isso significa que, quando ocorrem alterações, você precisa de algum modo de reconciliar essas alterações entre diferentes modelos.That means that when changes occur, you need some way to reconcile changes across the different models. Uma solução é consistência eventual e comunicação controlada por evento com base em mensagens assíncronas.A solution is eventual consistency and event-driven communication based on asynchronous messaging.

Ao usar mensagens, processos se comunicam trocando mensagens de maneira assíncrona.When using messaging, processes communicate by exchanging messages asynchronously. Um cliente faz um comando ou uma solicitação a um serviço ao enviar uma mensagem a ele.A client makes a command or a request to a service by sending it a message. Se o serviço precisar responder, ele enviará uma mensagem diferente de volta ao cliente.If the service needs to reply, it sends a different message back to the client. Como é uma comunicação baseada em mensagens, o cliente presume que a resposta não será recebida imediatamente e que poderá não haver resposta alguma.Since it's a message-based communication, the client assumes that the reply won't be received immediately, and that there might be no response at all.

Uma mensagem é composta por um cabeçalho (metadados como informações de identificação ou de segurança) e um corpo.A message is composed by a header (metadata such as identification or security information) and a body. As mensagens geralmente são enviadas por meio de protocolos assíncronos, como AMQP.Messages are usually sent through asynchronous protocols like AMQP.

A infraestrutura preferencial para esse tipo de comunicação na comunidade de microsserviços é um agente de mensagem leve, que é diferente de agentes e orquestradores grandes usados em SOA.The preferred infrastructure for this type of communication in the microservices community is a lightweight message broker, which is different than the large brokers and orchestrators used in SOA. Em um agente de mensagem leve, a infraestrutura é normalmente "inútil," atuando somente como um agente de mensagens, com implantações simples como RabbitMQ ou um barramento de serviço escalonável na nuvem como o Barramento de Serviço do Azure.In a lightweight message broker, the infrastructure is typically "dumb," acting only as a message broker, with simple implementations such as RabbitMQ or a scalable service bus in the cloud like Azure Service Bus. Nesse cenário, a maioria do pensamento "inteligente" ainda está nos pontos de extremidade que estão produzindo e consumindo mensagens; ou seja, nos microsserviços.In this scenario, most of the "smart" thinking still lives in the endpoints that are producing and consuming messages-that is, in the microservices.

Outra regra que você deve tentar seguir o máximo possível é usar apenas mensagens assíncronas entre os serviços internos e usar comunicação síncrona (como HTTP) apenas dos aplicativos cliente para os serviços de front-end (gateways de API mais o primeiro nível de microsserviços).Another rule you should try to follow, as much as possible, is to use only asynchronous messaging between the internal services, and to use synchronous communication (such as HTTP) only from the client apps to the front-end services (API Gateways plus the first level of microservices).

Há dois tipos de comunicação assíncrona de mensagens: comunicação baseada em mensagens do receptor único e comunicação baseada em mensagens de vários receptores.There are two kinds of asynchronous messaging communication: single receiver message-based communication, and multiple receivers message-based communication. As seções a seguir fornecem detalhes sobre eles.The following sections provide details about them.

Comunicação baseada em mensagem de destinatário únicoSingle-receiver message-based communication

Comunicação assíncrona baseada em mensagem com um único destinatário significa que há comunicação ponto a ponto que entrega uma mensagem a exatamente um dos consumidores que está lendo do canal e que essa mensagem é processada apenas uma vez.Message-based asynchronous communication with a single receiver means there's point-to-point communication that delivers a message to exactly one of the consumers that's reading from the channel, and that the message is processed just once. No entanto, existem situações especiais.However, there are special situations. Por exemplo, em um sistema de nuvem que tenta se recuperar automaticamente de falhas, a mesma mensagem pode ser enviada várias vezes.For instance, in a cloud system that tries to automatically recover from failures, the same message could be sent multiple times. Devido à rede ou outras falhas, o cliente deve ser capaz de tentar novamente enviar as mensagens, e o servidor precisa implementar uma operação para ser idempotente para processar uma mensagem específica apenas uma vez.Due to network or other failures, the client has to be able to retry sending messages, and the server has to implement an operation to be idempotent in order to process a particular message just once.

A comunicação baseada em mensagem destinatário único é especialmente adequada para enviar comandos assíncronos de um microsserviço para outro, conforme mostrado na Figura 4-18 que ilustra essa abordagem.Single-receiver message-based communication is especially well suited for sending asynchronous commands from one microservice to another as shown in Figure 4-18 that illustrates this approach.

Depois de começar a enviar comunicação baseada em mensagens (seja com comandos ou eventos), você deve evitar misturar comunicação baseada em mensagem com comunicação HTTP síncrona.Once you start sending message-based communication (either with commands or events), you should avoid mixing message-based communication with synchronous HTTP communication.

Um único microsserviço recebendo uma mensagem assíncrona

Figura 4-18.Figure 4-18. Um único microsserviço recebendo uma mensagem assíncronaA single microservice receiving an asynchronous message

Observe que, quando os comandos provém de aplicativos cliente, eles podem ser implementados como comandos síncronos HTTP.Note that when the commands come from client applications, they can be implemented as HTTP synchronous commands. Você deve usar comandos baseados em mensagens quando precisar de maior escalabilidade ou quando já estiver em um processo empresarial baseado em mensagem.You should use message-based commands when you need higher scalability or when you're already in a message-based business process.

Comunicação baseada em mensagens de vários destinatáriosMultiple-receivers message-based communication

Como uma abordagem mais flexível, você também poderá usar um mecanismo de publicação/assinatura para que a sua comunicação do remetente esteja disponível a microsserviços de assinante adicionais ou para aplicativos externos.As a more flexible approach, you might also want to use a publish/subscribe mechanism so that your communication from the sender will be available to additional subscriber microservices or to external applications. Portanto, ele o ajuda a seguir o princípio de abrir/fechar no serviço de envio.Thus, it helps you to follow the open/closed principle in the sending service. Dessa forma, mais assinantes podem ser adicionados no futuro sem necessidade de modificar o serviço do remetente.That way, additional subscribers can be added in the future without the need to modify the sender service.

Ao usar uma comunicação de publicação/assinatura, talvez você esteja usando uma interface de barramento de eventos para publicar eventos a qualquer assinante.When you use a publish/subscribe communication, you might be using an event bus interface to publish events to any subscriber.

Comunicação controlada por evento assíncronoAsynchronous event-driven communication

Ao usar comunicação controlada por evento assíncrono, um microsserviço publica um evento de integração quando acontece algo em seu domínio e outro microsserviço precisa estar ciente disso, como uma alteração de preço em um microsserviço do catálogo de produtos.When using asynchronous event-driven communication, a microservice publishes an integration event when something happens within its domain and another microservice needs to be aware of it, like a price change in a product catalog microservice. Microsserviços adicionais assinam os eventos para que possam recebê-los de maneira assíncrona.Additional microservices subscribe to the events so they can receive them asynchronously. Quando isso acontece, os receptores podem atualizar as próprias entidades de domínio, o que podem causar a publicação de mais eventos de integração.When that happens, the receivers might update their own domain entities, which can cause more integration events to be published. Este sistema de publicação/assinatura normalmente é executado por meio de uma implementação de um barramento de evento.This publish/subscribe system is usually performed by using an implementation of an event bus. O barramento de evento pode ser projetado como uma abstração ou interface, com a API que é necessária para assinar ou cancelar a assinatura de eventos e para publicar eventos.The event bus can be designed as an abstraction or interface, with the API that's needed to subscribe or unsubscribe to events and to publish events. O barramento de evento também pode ter uma ou mais implementações com base em qualquer agente de mensagens e entre processos, como uma fila de mensagens ou barramento de serviço que seja compatível com a comunicação assíncrona e um modelo de publicação/assinatura.The event bus can also have one or more implementations based on any inter-process and messaging broker, like a messaging queue or service bus that supports asynchronous communication and a publish/subscribe model.

Se um sistema usa consistência eventual orientada por eventos de integração, é recomendável que essa abordagem fique completamente clara para o usuário final.If a system uses eventual consistency driven by integration events, it's recommended that this approach is made completely clear to the end user. O sistema não deve usar uma abordagem que simule eventos de integração, como sistemas de sondagem ou SignalR do cliente.The system shouldn't use an approach that mimics integration events, like SignalR or polling systems from the client. O usuário final e o proprietário da empresa precisam adotar explicitamente consistência eventual no sistema e observar que, em muitos casos, os negócios não têm nenhum problema com essa abordagem, desde que ela seja explícita.The end user and the business owner have to explicitly embrace eventual consistency in the system and realize that in many cases the business doesn't have any problem with this approach, as long as it's explicit. Isso é importante porque os usuários podem esperar ver alguns resultados imediatamente e isso pode não acontecer com a consistência eventual.This is important because users might expect to see some results immediately and this might not happen with eventual consistency.

Conforme observado anteriormente na seção Desafios e soluções para o gerenciamento de dados distribuídos, você pode usar eventos de integração para implementar as tarefas de negócios que abrangem vários microsserviços.As noted earlier in the Challenges and solutions for distributed data management section, you can use integration events to implement business tasks that span multiple microservices. Assim, você terá consistência eventual entre esses serviços.Thus, you'll have eventual consistency between those services. Uma transação eventualmente consistente é composta por uma coleção de ações distribuídas.An eventually consistent transaction is made up of a collection of distributed actions. Em cada ação, o microsserviço relacionado atualiza uma entidade de domínio e publica outro evento de integração que gera a próxima ação dentro da mesma tarefa comercial de ponta a ponta.At each action, the related microservice updates a domain entity and publishes another integration event that raises the next action within the same end-to-end business task.

Um ponto importante é que você pode querer comunicar-se com vários microsserviços inscritos para o mesmo evento.An important point is that you might want to communicate to multiple microservices that are subscribed to the same event. Para fazer isso, você pode usar mensagens de publicação/assinatura com base em comunicação controlada por evento, conforme mostra a Figura 4-19.To do so, you can use publish/subscribe messaging based on event-driven communication, as shown in Figure 4-19. Esse mecanismo de publicação/assinatura não é exclusivo da arquitetura de microsserviço.This publish/subscribe mechanism isn't exclusive to the microservice architecture. Ele é semelhante à maneira como Contextos Limitados no DDD devem se comunicar ou à maneira como você propaga atualizações do banco de dados de gravação para o banco de dados de leitura no padrão de arquitetura de CQRS (Segregação de Responsabilidade de Comando e Consulta).It's similar to the way Bounded Contexts in DDD should communicate, or to the way you propagate updates from the write database to the read database in the Command and Query Responsibility Segregation (CQRS) architecture pattern. A meta é ter consistência eventual entre várias fontes de dados em seu sistema distribuído.The goal is to have eventual consistency between multiple data sources across your distributed system.

Diagrama mostrando comunicações assíncronas controladas por eventos.

Figura 4-19.Figure 4-19. Comunicação de mensagem controlada por evento assíncronoAsynchronous event-driven message communication

Na comunicação controlada por evento assíncrono, um microsserviço publica os eventos para um barramento de evento e muitos microsserviços podem assiná-lo para serem notificados e agirem sobre ele.In asynchronous event-driven communication one microservice publishes events to an event bus and many microservices can subscribe to it, to get notified and act on it. Sua implementação determinará o protocolo a ser usado para comunicações controladas por eventos e baseadas em mensagem.Your implementation will determine what protocol to use for event-driven, message-based communications. O AMQP pode ajudar a obter uma comunicação confiável na fila.AMQP can help achieve reliable queued communication.

Ao usar um barramento de evento, talvez você queira usar um nível de abstração (como uma interface de barramento de evento) com base em uma implementação relacionada em classes com o código usando a API de um agente de mensagens como RabbitMQ ou um barramento de serviço como Barramento de Serviço do Azure com Tópicos.When you use an event bus, you might want to use an abstraction level (like an event bus interface) based on a related implementation in classes with code using the API from a message broker like RabbitMQ or a service bus like Azure Service Bus with Topics. Como alternativa, você talvez queira usar um barramento de serviço de nível superior, como NServiceBus, MassTransit ou Brighter para articular seu barramento de evento e sistema de publicação/assinatura.Alternatively, you might want to use a higher-level service bus like NServiceBus, MassTransit, or Brighter to articulate your event bus and publish/subscribe system.

Uma observação sobre tecnologias para mensagens para sistemas de produçãoA note about messaging technologies for production systems

As tecnologias de mensagens disponíveis para implementar seu barramento do evento abstrato estão em diferentes níveis.The messaging technologies available for implementing your abstract event bus are at different levels. Por exemplo, produtos, como RabbitMQ (um transporte do agente de mensagens) e o Barramento de Serviço do Azure ficam em um nível inferior a outros produtos, como NServiceBus, MassTransit ou Brighter, que podem funcionar sobre RabbitMQ e o Barramento de Serviço do Azure.For instance, products like RabbitMQ (a messaging broker transport) and Azure Service Bus sit at a lower level than other products like, NServiceBus, MassTransit, or Brighter, which can work on top of RabbitMQ and Azure Service Bus. Sua escolha depende de quantos recursos avançados no nível do aplicativo e escalabilidade imediata você precisa para seu aplicativo.Your choice depends on how many rich features at the application level and out-of-the-box scalability you need for your application. Para implementar apenas um barramento de evento de prova de conceito para seu ambiente de desenvolvimento, como foi feito no exemplo de eShopOnContainers, pode ser suficiente uma implementação simples sobre RabbitMQ em execução em um contêiner do Docker.For implementing just a proof-of-concept event bus for your development environment, as it was done in the eShopOnContainers sample, a simple implementation on top of RabbitMQ running on a Docker container might be enough.

No entanto, para sistemas críticos e de produção que precisam de hiperescalabilidade, talvez você queira avaliar o Barramento de Serviço do Azure.However, for mission-critical and production systems that need hyper-scalability, you might want to evaluate Azure Service Bus. Para abstrações de alto nível e recursos que tornam o desenvolvimento de aplicativos distribuídos mais fácil, recomendamos que você avalie outros barramentos de serviço de software livre e comerciais, como NServiceBus, MassTransit e Brighter.For high-level abstractions and features that make the development of distributed applications easier, we recommend that you evaluate other commercial and open-source service buses, such as NServiceBus, MassTransit, and Brighter. É claro que você pode criar seus próprios recursos de barramento de serviço sobre tecnologias de nível inferior, como RabbitMQ e Docker.Of course, you can build your own service-bus features on top of lower-level technologies like RabbitMQ and Docker. Mas esse trabalho pode custar muito caro para um aplicativo empresarial personalizado.But that plumbing work might cost too much for a custom enterprise application.

Publicação resiliente para o barramento de eventoResiliently publishing to the event bus

Um desafio ao implementar uma arquitetura orientada a eventos em vários microsserviços é como atualizar atomicamente o estado no microsserviço original enquanto publica de maneira resiliente o evento de integração relacionado no barramento de evento, de alguma maneira baseado em transações.A challenge when implementing an event-driven architecture across multiple microservices is how to atomically update state in the original microservice while resiliently publishing its related integration event into the event bus, somehow based on transactions. A seguir estão algumas maneiras de fazer isso, embora haja outras abordagens também.The following are a few ways to accomplish this, although there could be additional approaches as well.

  • Usando uma fila transacional (baseada em DTC) como MSMQ.Using a transactional (DTC-based) queue like MSMQ. (No entanto, essa é uma abordagem herdada.)(However, this is a legacy approach.)

  • Usando mineração do log de transações.Using transaction log mining.

  • Usando o padrão Event Sourcing completo.Using full Event Sourcing pattern.

  • Usando o Padrão de caixa de saída: uma tabela de banco de dados transacional como uma fila de mensagens que será a base de um componente do criador do evento que criará e publicará o evento.Using the Outbox pattern: a transactional database table as a message queue that will be the base for an event-creator component that would create the event and publish it.

Tópicos adicionais a serem considerados ao usar comunicação assíncrona são idempotência de mensagem e eliminação de duplicação de mensagem.Additional topics to consider when using asynchronous communication are message idempotence and message deduplication. Esses tópicos são abordados na seção Implementar a comunicação baseada em eventos entre microsserviços (eventos de integração) mais adiante neste guia.These topics are covered in the section Implementing event-based communication between microservices (integration events) later in this guide.

Recursos adicionaisAdditional resources