Comunicação em uma arquitetura de microsserviçoCommunication in a microservice architecture

Em um aplicativo monolítico em execução em um único processo, os componentes invocam-se usando um método no nível da linguagem ou chamadas de função.In a monolithic application running on a single process, components invoke one another using language-level method or function calls. Eles poderão ser fortemente acoplados se você estiver criando objetos com código (por exemplo, new ClassName()) ou poderão ser invocados de forma desacoplada, se você estiver usando injeção de dependência referenciando abstrações em vez de instâncias concretas de objeto.These can be strongly coupled if you're creating objects with code (for example, new ClassName()), or can be invoked in a decoupled way if you're using Dependency Injection by referencing abstractions rather than concrete object instances. De qualquer forma, os objetos são executados no mesmo processo.Either way, the objects are running within the same process. O maior desafio ao passar de um aplicativo monolítico para um aplicativo baseado em microsserviços é alterar o mecanismo de comunicação.The biggest challenge when changing from a monolithic application to a microservices-based application lies in changing the communication mechanism. Uma conversão direta das chamadas de método internas em processo em chamadas RPC para os serviços causará uma comunicação muito intensa e ineficiente que não terá um bom desempenho em ambientes distribuídos.A direct conversion from in-process method calls into RPC calls to services will cause a chatty and not efficient communication that won't perform well in distributed environments. Os desafios da criação adequada de um sistema distribuído são tão conhecidos que existe um código conhecido como Fallacies of distributed computing (Enganos da computação distribuída) que lista as suposições que os desenvolvedores geralmente fazem ao passar de designs monolíticos para designs distribuídos.The challenges of designing distributed system properly are well enough known that there's even a canon known as the Fallacies of distributed computing that lists assumptions that developers often make when moving from monolithic to distributed designs.

Não há apenas uma solução, mas várias.There isn't one solution, but several. Uma das soluções envolve isolar os microsserviços de negócios o máximo possível.One solution involves isolating the business microservices as much as possible. Em seguida, usar a comunicação assíncrona entre os microsserviços internos e substituir a comunicação refinada típica na comunicação entre processos dos objetos por uma comunicação menos refinada.You then use asynchronous communication between the internal microservices and replace fine-grained communication that's typical in intra-process communication between objects with coarser-grained communication. Você pode fazer isso agrupando chamadas e retornando para o cliente dados que agregam os resultados de várias chamadas internas.You can do this by grouping calls, and by returning data that aggregates the results of multiple internal calls, to the client.

Um aplicativo baseado em microsserviços é um sistema distribuído em execução em vários processos ou serviços, geralmente, até mesmo em vários servidores ou hosts.A microservices-based application is a distributed system running on multiple processes or services, usually even across multiple servers or hosts. Cada instância de serviço geralmente é um processo.Each service instance is typically a process. Portanto, os serviços devem interagir usando um protocolo de comunicação entre processos, como HTTP, AMQP ou um protocolo binário, como TCP, dependendo da natureza de cada serviço.Therefore, services must interact using an inter-process communication protocol such as HTTP, AMQP, or a binary protocol like TCP, depending on the nature of each service.

A comunidade de microsserviços promove a filosofia de "pontos de extremidade inteligentes e pipes tolos" Este slogan incentiva um design o mais desacoplado possível entre os microsserviços e o mais coeso possível dentro de um único microsserviço.The microservice community promotes the philosophy of "smart endpoints and dumb pipes" This slogan encourages a design that's as decoupled as possible between microservices, and as cohesive as possible within a single microservice. Conforme explicado anteriormente, cada microsserviço tem seus próprios dados e sua própria lógica do domínio.As explained earlier, each microservice owns its own data and its own domain logic. Mas os microsserviços que compõem um aplicativo de ponta a ponta geralmente são coreografados simplesmente usando comunicações REST em vez de protocolos complexos, como WS-*, e comunicações flexíveis controladas por evento, em vez de orquestradores de negócios e processos centralizados.But the microservices composing an end-to-end application are usually simply choreographed by using REST communications rather than complex protocols such as WS-* and flexible event-driven communications instead of centralized business-process-orchestrators.

Os dois protocolos mais usados são solicitação/resposta HTTP com APIs de recurso (principalmente em consultas) e mensagens assíncronas leves, ao comunicar atualizações entre vários microsserviços.The two commonly used protocols are HTTP request/response with resource APIs (when querying most of all), and lightweight asynchronous messaging when communicating updates across multiple microservices. Isso será mais bem explicado nas seções a seguir.These are explained in more detail in the following sections.

Tipos de comunicaçãoCommunication types

O cliente e os serviços podem se comunicar por vários tipos de comunicação diferentes, cada um direcionando a um cenário diferente e a metas diferentes.Client and services can communicate through many different types of communication, each one targeting a different scenario and goals. Inicialmente, esses tipos de comunicação podem ser classificados em dois eixos.Initially, those types of communications can be classified in two axes.

O primeiro eixo define se o protocolo é síncrono ou assíncrono:The first axis defines if the protocol is synchronous or asynchronous:

  • Protocolo síncrono.Synchronous protocol. HTTP é um protocolo síncrono.HTTP is a synchronous protocol. O cliente envia uma solicitação e espera uma resposta do serviço.The client sends a request and waits for a response from the service. Isso é independente da execução do código do cliente que pode ser síncrona (o thread é bloqueado) ou assíncrona (o thread não é bloqueado e a resposta acabará alcançando um retorno de chamada).That's independent of the client code execution that could be synchronous (thread is blocked) or asynchronous (thread isn't blocked, and the response will reach a callback eventually). O ponto importante aqui é que o protocolo (HTTP/HTTPS) é síncrono e o código do cliente somente poderá continuar sua tarefa quando receber a resposta do servidor HTTP.The important point here is that the protocol (HTTP/HTTPS) is synchronous and the client code can only continue its task when it receives the HTTP server response.

  • Protocolo assíncrono.Asynchronous protocol. Outros protocolos, como o AMQP (um protocolo compatível com vários sistemas operacionais e ambientes de nuvem), usam mensagens assíncronas.Other protocols like AMQP (a protocol supported by many operating systems and cloud environments) use asynchronous messages. O código do cliente ou o remetente da mensagem geralmente não espera uma resposta.The client code or message sender usually doesn't wait for a response. Ele apenas envia a mensagem como ao enviar uma mensagem para uma fila do RabbitMQ ou para qualquer outro agente de mensagens.It just sends the message as when sending a message to a RabbitMQ queue or any other message broker.

O segundo eixo define se a comunicação tem um único destinatário ou vários destinatários:The second axis defines if the communication has a single receiver or multiple receivers:

  • Único destinatário.Single receiver. Cada solicitação deve ser processada por exatamente um destinatário ou serviço.Each request must be processed by exactly one receiver or service. Um exemplo dessa comunicação é o Padrão de comando.An example of this communication is the Command pattern.

  • Vários destinatários.Multiple receivers. Cada solicitação pode ser processada por nenhum destinatário, por um ou por vários destinatários.Each request can be processed by zero to multiple receivers. Esse tipo de comunicação precisa ser assíncrono.This type of communication must be asynchronous. Um exemplo é o mecanismo de publicação/assinatura usado em padrões como a Arquitetura orientada por eventos.An example is the publish/subscribe mechanism used in patterns like Event-driven architecture. Ele se baseia em um agente de mensagem ou em uma interface de barramento de evento ao propagar atualizações de dados entre vários microsserviços por meio de eventos. Ele geralmente é implementado por meio de um barramento de serviço ou artefato semelhante, como o Barramento de Serviço do Azure, usando tópicos e assinaturas.This is based on an event-bus interface or message broker when propagating data updates between multiple microservices through events; it's usually implemented through a service bus or similar artifact like Azure Service Bus by using topics and subscriptions.

Um aplicativo baseado em microsserviço geralmente usará uma combinação desses estilos de comunicação.A microservice-based application will often use a combination of these communication styles. O tipo mais comum é a comunicação de único destinatário com um protocolo síncrono como HTTP/HTTPS ao invocar um serviço HTTP de API Web regular.The most common type is single-receiver communication with a synchronous protocol like HTTP/HTTPS when invoking a regular Web API HTTP service. Geralmente os microsserviços também usam protocolos de mensagens para a comunicação assíncrona entre eles.Microservices also typically use messaging protocols for asynchronous communication between microservices.

É bom conhecer esses eixos para esclarecer melhor os mecanismos de comunicação possíveis, mas eles não são as questões mais importantes ao criar microsserviços.These axes are good to know so you have clarity on the possible communication mechanisms, but they're not the important concerns when building microservices. Não é a natureza assíncrona da execução de thread de cliente nem a natureza assíncrona do protocolo selecionado os pontos mais importantes ao integrar microsserviços.Neither the asynchronous nature of client thread execution nor the asynchronous nature of the selected protocol are the important points when integrating microservices. O que é importante é ser capaz de integrar os microsserviços de forma assíncrona, mantendo a independência dos microsserviços, conforme será explicado na seção a seguir.What is important is being able to integrate your microservices asynchronously while maintaining the independence of microservices, as explained in the following section.

A integração assíncrona dos microsserviços impõe a autonomia do microsserviçoAsynchronous microservice integration enforces microservice's autonomy

Conforme mencionado, o ponto importante ao criar um aplicativo baseado em microsserviços é a maneira de integrar os microsserviços.As mentioned, the important point when building a microservices-based application is the way you integrate your microservices. O ideal é tentar minimizar a comunicação entre os microsserviços internos.Ideally, you should try to minimize the communication between the internal microservices. Quanto menos comunicações entre os microsserviços, melhor.The fewer communications between microservices, the better. Mas, em muitos casos, será necessário integrar os microsserviços de alguma forma.But in many cases, you'll have to somehow integrate the microservices. Quando isso for necessário, a regra crítica será que a comunicação entre os microsserviços deve ser assíncrona.When you need to do that, the critical rule here is that the communication between the microservices should be asynchronous. Isso não significa que você precisa usar um protocolo específico (por exemplo, um sistema de mensagens assíncrono em vez de HTTP síncrono).That doesn't mean that you have to use a specific protocol (for example, asynchronous messaging versus synchronous HTTP). Isso apenas significa que a comunicação entre os microsserviços deve ser feita somente pela propagação de dados de forma assíncrona, mas tente não depender de outros microsserviços internos como parte da operação inicial de solicitação/resposta HTTP do serviço.It just means that the communication between microservices should be done only by propagating data asynchronously, but try not to depend on other internal microservices as part of the initial service's HTTP request/response operation.

Se possível, nunca dependa da comunicação síncrona (solicitação/resposta) entre vários microsserviços, nem mesmo para consultas.If possible, never depend on synchronous communication (request/response) between multiple microservices, not even for queries. O objetivo de cada microsserviço é ser autônomo e estar disponível para o consumidor cliente, mesmo se outros serviços que façam parte do aplicativo de ponta a ponta estiverem inativos ou não íntegros.The goal of each microservice is to be autonomous and available to the client consumer, even if the other services that are part of the end-to-end application are down or unhealthy. Se você acha que precisa fazer uma chamada de um microsserviço para outros microsserviços (como executar uma solicitação HTTP para uma consulta de dados) para poder fornecer uma resposta a um aplicativo cliente, você tem uma arquitetura que não será resiliente quando alguns microsserviços falharem.If you think you need to make a call from one microservice to other microservices (like performing an HTTP request for a data query) to be able to provide a response to a client application, you have an architecture that won't be resilient when some microservices fail.

Além disso, as dependências de HTTP entre os microsserviços, como ao criar longos ciclos de solicitação/resposta com cadeias de solicitação HTTP, como foi mostrado na primeira parte da Figura 4-15, não permitem que os microsserviços sejam autônomos e também afetam o desempenho dos microsserviços quando um dos serviços nessa cadeia não é executado corretamente.Moreover, having HTTP dependencies between microservices, like when creating long request/response cycles with HTTP request chains, as shown in the first part of the Figure 4-15, not only makes your microservices not autonomous but also their performance is impacted as soon as one of the services in that chain isn't performing well.

Quanto mais você adicionar dependências síncronas entre os microsserviços, como solicitações de consulta, pior será o tempo de resposta geral para os aplicativos clientes.The more you add synchronous dependencies between microservices, such as query requests, the worse the overall response time gets for the client apps.

Na comunicação síncrona, uma “cadeia” de solicitações é criada entre microsserviços ao atender à solicitação do cliente.

Figura 4-15.Figure 4-15. Antipadrões e padrões na comunicação entre microsserviçosAnti-patterns and patterns in communication between microservices

Se seu microsserviço precisar gerar uma ação adicional em outro microsserviço, se possível, não execute essa ação de forma síncrona e como parte da operação original de solicitação e resposta do microsserviço.If your microservice needs to raise an additional action in another microservice, if possible, do not perform that action synchronously and as part of the original microservice request and reply operation. Nesse caso, faça isso de forma assíncrona (usando o serviço de mensagens assíncrono ou eventos de integração, filas, etc.).Instead, do it asynchronously (using asynchronous messaging or integration events, queues, etc.). No entanto, tanto quanto possível, não invoque a ação de forma síncrona como parte da operação de solicitação e resposta síncrona original.But, as much as possible, do not invoke the action synchronously as part of the original synchronous request and reply operation.

E, finalmente, (e este é o momento em que maioria dos problemas surgem ao criar microsserviços), se o microsserviço inicial precisar de dados que sejam originalmente pertencentes a outros microsserviços, não confie em fazer solicitações síncronas para esses dados.And finally (and this is where most of the issues arise when building microservices), if your initial microservice needs data that's originally owned by other microservices, do not rely on making synchronous requests for that data. Nesse caso, replique ou propague esses dados (somente os atributos necessários) para o banco de dados do serviço inicial usando consistência eventual (normalmente com eventos de integração, conforme será explicado nas próximas seções).Instead, replicate or propagate that data (only the attributes you need) into the initial service's database by using eventual consistency (typically by using integration events, as explained in upcoming sections).

Conforme observado anteriormente na seção Identificando limites de modelo de domínio para cada microsserviço, a duplicação de alguns dados entre vários microsserviços não é um design errado, ao contrário, ao fazer isso, é possível converter os dados na linguagem específica ou nos termos desse domínio adicional ou do Contexto Limitado.As noted earlier in the section Identifying domain-model boundaries for each microservice, duplicating some data across several microservices isn't an incorrect design—on the contrary, when doing that you can translate the data into the specific language or terms of that additional domain or Bounded Context. Por exemplo, no aplicativo eShopOnContainers há um microsserviço chamado identity.api que é responsável pela maioria dos dados do usuário com uma entidade chamada Usuário.For instance, in the eShopOnContainers application you have a microservice named identity.api that's in charge of most of the user's data with an entity named User. No entanto, quando for necessário armazenar dados sobre o usuário dentro do microsserviço de pedidos, armazene-os como uma entidade diferente chamada Comprador.However, when you need to store data about the user within the Ordering microservice, you store it as a different entity named Buyer. A entidade Comprador compartilha a mesma identidade com a entidade Usuário original, mas pode ter apenas alguns atributos necessários para o domínio de pedidos e não o perfil do usuário completo.The Buyer entity shares the same identity with the original User entity, but it might have only the few attributes needed by the Ordering domain, and not the whole user profile.

Você pode usar qualquer protocolo para comunicar e propagar dados de forma assíncrona entre os microsserviços para garantir a consistência eventual.You might use any protocol to communicate and propagate data asynchronously across microservices in order to have eventual consistency. Conforme mencionado, você pode usar eventos de integração com um barramento de evento, com um agente de mensagem ou até mesmo com sondagem HTTP dos outros serviços.As mentioned, you could use integration events using an event bus or message broker or you could even use HTTP by polling the other services instead. Não importa.It doesn't matter. A regra importante é não criar dependências síncronas entre os microsserviços.The important rule is to not create synchronous dependencies between your microservices.

As seções a seguir explicam os vários estilos de comunicação que você pode considerar para um aplicativo baseado em microsserviço.The following sections explain the multiple communication styles you can consider using in a microservice-based application.

Estilos de comunicaçãoCommunication styles

Existem vários protocolos e opções que você pode usar para comunicação, dependendo do tipo de comunicação que deseja usar.There are many protocols and choices you can use for communication, depending on the communication type you want to use. Se você estiver usando um mecanismo de comunicação baseado em solicitação/resposta síncrona, protocolos como HTTP e REST serão os mais comuns, principalmente se você estiver publicando serviços fora do host do Docker ou do cluster de microsserviços.If you're using a synchronous request/response-based communication mechanism, protocols such as HTTP and REST approaches are the most common, especially if you're publishing your services outside the Docker host or microservice cluster. Se você estiver fazendo a comunicação entre serviços internamente (no host do Docker ou no cluster de microsserviços), também será possível usar os mecanismos de comunicação de formato binário (como o WCF usando TCP e o formato binário).If you're communicating between services internally (within your Docker host or microservices cluster), you might also want to use binary format communication mechanisms (like WCF using TCP and binary format). Como alternativa, você pode usar mecanismos de comunicação assíncrona baseada em mensagem, como o AMQP.Alternatively, you can use asynchronous, message-based communication mechanisms such as AMQP.

Também há vários formatos de mensagem como JSON ou XML, ou até mesmo formatos binários, que podem ser mais eficientes.There are also multiple message formats like JSON or XML, or even binary formats, which can be more efficient. Se o formato binário escolhido não for um padrão, provavelmente, não será uma boa ideia publicar os serviços publicamente usando esse formato.If your chosen binary format isn't a standard, it's probably not a good idea to publicly publish your services using that format. É possível usar um formato não padrão para a comunicação interna entre os microsserviços.You could use a non-standard format for internal communication between your microservices. Você pode fazer isso na comunicação entre os microsserviços dentro do host do Docker ou do cluster de microsserviços (por exemplo, orquestradores do Docker) ou para aplicativos cliente do proprietário que se comunicam com os microsserviços.You might do this when communicating between microservices within your Docker host or microservice cluster (for example, Docker orchestrators), or for proprietary client applications that talk to the microservices.

Comunicação de solicitação/resposta com HTTP e RESTRequest/response communication with HTTP and REST

Quando um cliente usa a comunicação de solicitação/resposta, ele envia uma solicitação para um serviço e, em seguida, o serviço processa a solicitação e retorna uma resposta.When a client uses request/response communication, it sends a request to a service, then the service processes the request and sends back a response. A comunicação de solicitação/resposta é muito adequada principalmente para consultar dados de uma interface do usuário em tempo real (uma interface do usuário em tempo real) dos aplicativos clientes.Request/response communication is especially well suited for querying data for a real-time UI (a live user interface) from client apps. Portanto, em uma arquitetura de microsserviço provavelmente você usará esse mecanismo de comunicação para a maioria das consultas, conforme mostrado na Figura 4-16.Therefore, in a microservice architecture you'll probably use this communication mechanism for most queries, as shown in Figure 4-16.

É possível usar a comunicação de solicitação/resposta para consultas ao vivo quando o cliente envia a solicitação a um Gateway de API, supondo que a resposta de microsserviços chegará em um período muito curto.

Figura 4-16.Figure 4-16. Usando a comunicação de solicitação/resposta HTTP (síncrona ou assíncrona)Using HTTP request/response communication (synchronous or asynchronous)

Quando um cliente usa a comunicação de solicitação/resposta, ele considera que a resposta chegará muito em breve, geralmente, em menos de um segundo ou, no máximo, em alguns segundos.When a client uses request/response communication, it assumes that the response will arrive in a short time, typically less than a second, or a few seconds at most. Para respostas em atraso, você precisa implementar a comunicação assíncrona baseada em padrões de sistema de mensagens e em tecnologias de sistema de mensagens, que é uma abordagem diferente que explicaremos na próxima seção.For delayed responses, you need to implement asynchronous communication based on messaging patterns and messaging technologies, which is a different approach that we explain in the next section.

Um estilo popular de arquitetura para comunicação de solicitação/resposta é o REST (Transferência de Estado Representacional).A popular architectural style for request/response communication is REST. Essa abordagem é baseada e fortemente vinculada ao protocolo HTTP, adotando verbos HTTP como GET, POST e PUT.This approach is based on, and tightly coupled to, the HTTP protocol, embracing HTTP verbs like GET, POST, and PUT. O REST é a abordagem de comunicação de arquitetura mais comum usada na criação de serviços.REST is the most commonly used architectural communication approach when creating services. Você pode implementar serviços REST ao desenvolver serviços de API Web ASP.NET Core.You can implement REST services when you develop ASP.NET Core Web API services.

Há um valor adicional ao usar serviços REST HTTP como sua linguagem IDL.There's additional value when using HTTP REST services as your interface definition language. Por exemplo, ao usar metadados do Swagger para descrever sua API de serviço, você poderá usar ferramentas que geram stubs de cliente para descobrir e consumir seus serviços diretamente.For instance, if you use Swagger metadata to describe your service API, you can use tools that generate client stubs that can directly discover and consume your services.

Recursos adicionaisAdditional resources

Comunicação por push e em tempo real baseada em HTTPPush and real-time communication based on HTTP

Outra possibilidade (geralmente para finalidades diferentes do REST) é uma comunicação em tempo real e de um-para-muitos com estruturas de nível mais alto, como ASP.NET SignalR e protocolos como WebSockets.Another possibility (usually for different purposes than REST) is a real-time and one-to-many communication with higher-level frameworks such as ASP.NET SignalR and protocols such as WebSockets.

Como mostra a Figura 4-17, a comunicação HTTP em tempo real significa que o código do servidor pode enviar conteúdo por push para os clientes conectados à medida que os dados ficam disponíveis, ou seja, o servidor não precisa esperar que um cliente solicite novos dados.As Figure 4-17 shows, real-time HTTP communication means that you can have server code pushing content to connected clients as the data becomes available, rather than having the server wait for a client to request new data.

O SignalR é uma boa maneira de atingir a comunicação em tempo real para enviar por push o conteúdo para os clientes de um servidor de back-end.

Figura 4-17.Figure 4-17. Comunicação de mensagem assíncrona de um-para-um em tempo realOne-to-one real-time asynchronous message communication

Como a comunicação ocorre em tempo real, os aplicativos clientes mostram as alterações quase instantaneamente.Since communication is in real time, client apps show the changes almost instantly. Geralmente, isso é tratado por um protocolo como WebSockets, usando várias conexões de WebSocket (uma por cliente).This is usually handled by a protocol such as WebSockets, using many WebSockets connections (one per client). Um exemplo típico é quando um serviço comunica uma alteração na pontuação de um jogo de esportes para vários aplicativos Web clientes simultaneamente.A typical example is when a service communicates a change in the score of a sports game to many client web apps simultaneously.