BLOG | NGINX

Construindo Microsserviços: Comunicação entre processos em uma arquitetura de microsserviços

NGINX-Parte-de-F5-horiz-preto-tipo-RGB
Miniatura de Chris Richardson
Chris Richardson
Publicado em 24 de julho de 2015

Editor – Esta série de artigos em sete partes está agora completa:

  1. Introdução aos Microsserviços
  2. Construindo Microsserviços: Usando um gateway de API
  3. Construindo Microsserviços: Comunicação entre processos em uma arquitetura de microsserviços (este artigo)
  4. Descoberta de serviços em uma arquitetura de microsserviços
  5. Gerenciamento de dados orientado a eventos para microsserviços
  6. Escolhendo uma estratégia de implantação de microsserviços
  7. Refatorando um monólito em microsserviços

Você também pode baixar o conjunto completo de artigos, além de informações sobre a implementação de microsserviços usando o NGINX Plus, como um e-book – Microsserviços: Do design à implantação . Além disso, confira a nova página Soluções de Microsserviços .

Este é o terceiro artigo da nossa série sobre como criar aplicativos com uma arquitetura de microsserviços. O primeiro artigo apresenta o padrão de Arquitetura de Microsserviços , compara-o com o padrão de Arquitetura Monolítica e discute os benefícios e desvantagens do uso de microsserviços. O segundo artigo descreve como os clientes de um aplicativo se comunicam com os microsserviços por meio de um intermediário conhecido como API Gateway . Neste artigo, veremos como os serviços dentro de um sistema se comunicam entre si. O quarto artigo explora o problema intimamente relacionado da descoberta de serviços.

INTRODUÇÃO

Em um aplicativo monolítico, os componentes invocam uns aos outros por meio de chamadas de métodos ou funções em nível de linguagem. Em contraste, um aplicativo baseado em microsserviços é um sistema distribuído executado em várias máquinas. Cada instância de serviço é normalmente um processo. Consequentemente, como mostra o diagrama a seguir, os serviços devem interagir usando um mecanismo de comunicação entre processos (IPC).


Em um aplicativo de microsserviços, os serviços precisam de um mecanismo de comunicação entre processos (IPC) (enquanto os módulos em um monólito podem chamar rotinas)

Mais tarde, veremos tecnologias IPC específicas, mas primeiro vamos explorar várias questões de design.

Estilos de interação

Ao selecionar um mecanismo de IPC para um serviço, é útil pensar primeiro em como os serviços interagem. Há uma variedade de estilos de interação cliente⇔serviço. Eles podem ser categorizados em duas dimensões. A primeira dimensão é se a interação é um-para-um ou um-para-muitos:

  • Um para um – Cada solicitação do cliente é processada por exatamente uma instância de serviço.
  • Um para muitos – Cada solicitação é processada por várias instâncias de serviço.

A segunda dimensão é se a interação é síncrona ou assíncrona:

  • Síncrono – O cliente espera uma resposta oportuna do serviço e pode até bloquear enquanto ele espera.
  • Assíncrono – O cliente não bloqueia enquanto espera por uma resposta, e a resposta, se houver, não é necessariamente enviada imediatamente.

A tabela a seguir mostra os vários estilos de interação.

  Um para um Um para muitos
Síncrono Solicitação/resposta  — 
Assíncrono Notificação Publicar/assinar
Solicitação/resposta assíncrona Respostas publicadas/assíncronas

Existem os seguintes tipos de interações um-para-um:

  • Solicitação/resposta – Um cliente faz uma solicitação a um serviço e aguarda uma resposta. O cliente espera que a resposta chegue em tempo hábil. Em um aplicativo baseado em thread, o thread que faz a solicitação pode até mesmo bloquear enquanto espera.
  • Notificação (também conhecida como solicitação unidirecional) – Um cliente envia uma solicitação a um serviço, mas nenhuma resposta é esperada ou enviada.
  • Solicitação/resposta assíncrona – Um cliente envia uma solicitação a um serviço, que responde de forma assíncrona. O cliente não bloqueia enquanto espera e é projetado com a suposição de que a resposta pode demorar um pouco para chegar.

Existem os seguintes tipos de interações um-para-muitos:

  • Publicar/assinar – Um cliente publica uma mensagem de notificação, que é consumida por zero ou mais serviços interessados.
  • Respostas de publicação/assíncronas – Um cliente publica uma mensagem de solicitação e aguarda um determinado período de tempo pelas respostas dos serviços interessados.

Cada serviço normalmente usa uma combinação desses estilos de interação. Para alguns serviços, um único mecanismo IPC é suficiente. Outros serviços podem precisar usar uma combinação de mecanismos de IPC. O diagrama a seguir mostra como os serviços em um aplicativo de táxi podem interagir quando o usuário solicita uma viagem.


Os serviços usam uma combinação de notificações, solicitação/resposta e publicação/assinatura. Por exemplo, o smartphone do passageiro envia uma notificação ao serviço Trip Management para solicitar uma coleta. O serviço de gerenciamento de viagens verifica se a conta do passageiro está ativa usando solicitação/resposta para invocar o serviço de passageiros. O serviço de gerenciamento de viagens cria a viagem e usa publicar/assinar para notificar outros serviços, incluindo o Dispatcher, que localiza um motorista disponível.

Agora que vimos os estilos de interação, vamos dar uma olhada em como definir APIs.

Definindo APIs

A API de um serviço é um contrato entre o serviço e seus clientes. Independentemente da sua escolha do mecanismo IPC, é importante definir precisamente a API de um serviço usando algum tipo de linguagem de definição de interface (IDL). Há até bons argumentos para usar uma abordagem API-first para definir serviços. Você começa o desenvolvimento de um serviço escrevendo a definição da interface e revisando-a com os desenvolvedores do cliente. Somente após iterar na definição da API você implementa o serviço. Fazer esse design antecipadamente aumenta suas chances de criar um serviço que atenda às necessidades de seus clientes.

Como você verá mais adiante neste artigo, a natureza da definição da API depende de qual mecanismo IPC você está usando. Se você estiver usando mensagens, a API consiste nos canais de mensagens e nos tipos de mensagens. Se você estiver usando HTTP, a API consiste em URLs e nos formatos de solicitação e resposta. Mais adiante descreveremos alguns IDLs com mais detalhes.

APIs em evolução

A API de um serviço muda invariavelmente ao longo do tempo. Em um aplicativo monolítico, geralmente é simples alterar a API e atualizar todos os chamadores. Em um aplicativo baseado em microsserviços, é muito mais difícil, mesmo que todos os consumidores da sua API sejam outros serviços no mesmo aplicativo. Normalmente, não é possível forçar todos os clientes a atualizarem em conjunto com o serviço. Além disso, você provavelmente implantará incrementalmente novas versões de um serviço, de modo que versões antigas e novas do serviço sejam executadas simultaneamente. É importante ter uma estratégia para lidar com essas questões.

A maneira como você lida com uma alteração de API depende do tamanho da alteração. Algumas alterações são pequenas e compatíveis com a versão anterior. Você pode, por exemplo, adicionar atributos a solicitações ou respostas. Faz sentido projetar clientes e serviços de modo que observem o princípio da robustez . Clientes que usam uma API mais antiga devem continuar trabalhando com a nova versão do serviço. O serviço fornece valores padrão para os atributos de solicitação ausentes e os clientes ignoram quaisquer atributos de resposta extras. É importante usar um mecanismo IPC e um formato de mensagem que permitam que você evolua facilmente suas APIs.

Às vezes, no entanto, você precisa fazer grandes mudanças incompatíveis em uma API. Como você não pode forçar os clientes a atualizarem imediatamente, um serviço precisa dar suporte a versões mais antigas da API por algum período de tempo. Se você estiver usando um mecanismo baseado em HTTP, como REST, uma abordagem é incorporar o número da versão na URL. Cada instância de serviço pode manipular várias versões simultaneamente. Como alternativa, você pode implantar instâncias diferentes, cada uma manipulando uma versão específica.

Lidando com falhas parciais

Conforme mencionado no artigo anterior sobre o API Gateway<.htmla>, em um sistema distribuído há o risco sempre presente de falha parcial. Como clientes e serviços são processos separados, um serviço pode não conseguir responder em tempo hábil à solicitação de um cliente. Um serviço pode estar inativo devido a uma falha ou para manutenção. Ou o serviço pode estar sobrecarregado e responder extremamente lentamente às solicitações.

Considere, por exemplo, o cenário Detalhes do produto desse artigo. Vamos imaginar que o Serviço de Recomendação não esteja respondendo. Uma implementação ingênua de um cliente pode bloquear a espera indefinidamente por uma resposta. Isso não só resultaria em uma experiência ruim para o usuário, mas em muitos aplicativos consumiria um recurso precioso, como um thread. Eventualmente, o tempo de execução ficaria sem threads e não responderia, como mostrado na figura a seguir.


Um aplicativo de microsserviços deve ser projetado para lidar com falhas parciais, ou então o tempo de execução pode ficar sem threads quando os clientes bloqueiam a espera por um serviço que não responde

Para evitar esse problema, é essencial que você projete seus serviços para lidar com falhas parciais.

Uma boa abordagem a seguir é a descrita pela Netflix . As estratégias para lidar com falhas parciais incluem:

  • Tempos limite de rede – Nunca bloqueie indefinidamente e sempre use tempos limite ao esperar por uma resposta. Usar tempos limite garante que os recursos nunca fiquem presos indefinidamente.
  • Limitar o número de solicitações pendentes – Imponha um limite máximo ao número de solicitações pendentes que um cliente pode ter com um serviço específico. Se o limite for atingido, provavelmente não fará sentido fazer solicitações adicionais, e essas tentativas precisam falhar imediatamente.
  • Padrão de disjuntor – Rastreie o número de solicitações bem-sucedidas e com falha. Se a taxa de erro exceder um limite configurado, desarme o disjuntor para que novas tentativas falhem imediatamente. Se um grande número de solicitações estiver falhando, isso sugere que o serviço está indisponível e que enviar solicitações é inútil. Após um período de tempo limite, o cliente deve tentar novamente e, se tiver sucesso, fechar o disjuntor.
  • Fornecer fallbacks – Execute lógica de fallback quando uma solicitação falhar. Por exemplo, retornar dados armazenados em cache ou um valor padrão, como um conjunto vazio de recomendações.

Netflix Hystrix é uma biblioteca de código aberto que implementa esses e outros padrões. Se você estiver usando a JVM, você definitivamente deve considerar usar o Hystrix. E, se você estiver executando em um ambiente não JVM, deverá usar uma biblioteca equivalente.

Tecnologias IPC

Há muitas tecnologias IPC diferentes para escolher. Os serviços podem usar mecanismos de comunicação baseados em solicitação/resposta síncrona, como REST baseado em HTTP ou Thrift. Como alternativa, eles podem usar mecanismos de comunicação assíncronos baseados em mensagens, como AMQP ou STOMP. Há também uma variedade de formatos de mensagens diferentes. Os serviços podem usar formatos baseados em texto legíveis por humanos, como JSON ou XML. Como alternativa, eles podem usar um formato binário (que é mais eficiente), como Avro ou Protocol Buffers. Mais tarde, veremos os mecanismos IPC síncronos, mas primeiro vamos discutir os mecanismos IPC assíncronos.

Comunicação assíncrona baseada em mensagens

Ao usar mensagens, os processos se comunicam por meio de troca de mensagens assíncrona. Um cliente faz uma solicitação a um serviço enviando uma mensagem. Se for esperado que o serviço responda, ele o fará enviando uma mensagem separada ao cliente. Como a comunicação é assíncrona, o cliente não fica bloqueado esperando por uma resposta. Em vez disso, o cliente é escrito assumindo que a resposta não será recebida imediatamente.

Uma mensagem consiste em cabeçalhos (metadados como o remetente) e um corpo de mensagem. As mensagens são trocadas por canais . Qualquer número de produtores pode enviar mensagens para um canal. Da mesma forma, qualquer número de consumidores pode receber mensagens de um canal. Existem dois tipos de canais: ponto a ponto e publicação-assinatura . Um canal ponto a ponto entrega uma mensagem exatamente para um dos consumidores que está lendo o canal. Os serviços usam canais ponto a ponto para os estilos de interação um a um descritos anteriormente. Um canal de publicação-assinatura entrega cada mensagem a todos os consumidores vinculados. Os serviços usam canais de publicação-assinatura para os estilos de interação de um para muitos descritos acima.

O diagrama a seguir mostra como o aplicativo de chamada de táxi pode usar canais de publicação-assinatura.


Microsserviços em aplicativos de táxi usam canais de publicação e assinatura para comunicação entre o despachante e outros serviços

O serviço de gerenciamento de viagens notifica serviços interessados, como o Dispatcher, sobre uma nova viagem escrevendo uma mensagem de viagem criada em um canal de publicação-assinatura. O Dispatcher encontra um driver disponível e notifica outros serviços escrevendo uma mensagem Driver Proposed em um canal de publicação-assinatura.

Há muitos sistemas de mensagens para escolher. Você deve escolher um que suporte uma variedade de linguagens de programação. Alguns sistemas de mensagens suportam protocolos padrão, como AMQP e STOMP. Outros sistemas de mensagens têm protocolos proprietários, mas documentados. Há um grande número de sistemas de mensagens de código aberto para escolher, incluindo RabbitMQ , Apache Kafka , Apache ActiveMQ e NSQ . Em um nível mais alto, todos eles apoiam alguma forma de mensagens e canais. Todos eles se esforçam para ser confiáveis, de alto desempenho e escaláveis. No entanto, há diferenças significativas nos detalhes do modelo de mensagens de cada corretor.

Há muitas vantagens em usar mensagens:

  • Desvincula o cliente do serviço – Um cliente faz uma solicitação simplesmente enviando uma mensagem para o canal apropriado. O cliente desconhece completamente as instâncias do serviço. Não é necessário usar um mecanismo de descoberta para determinar a localização de uma instância de serviço.
  • Buffering de mensagens – Com um protocolo de solicitação/resposta síncrona, como HTTP, tanto o cliente quanto o serviço devem estar disponíveis durante a troca. Em contraste, um corretor de mensagens enfileira as mensagens escritas em um canal até que elas possam ser processadas pelo consumidor. Isso significa, por exemplo, que uma loja online pode aceitar pedidos de clientes mesmo quando o sistema de atendimento de pedidos estiver lento ou indisponível. As mensagens de pedidos simplesmente ficam em fila.
  • Interações flexíveis de atendimento ao cliente – O sistema de mensagens oferece suporte a todos os estilos de interação descritos anteriormente.
  • Comunicação explícita entre processos – mecanismos baseados em RPC tentam fazer com que a invocação de um serviço remoto pareça a mesma que a chamada de um serviço local. Entretanto, devido às leis da física e à possibilidade de falha parcial, elas são de fato bem diferentes. As mensagens tornam essas diferenças bem explícitas para que os desenvolvedores não sejam enganados por uma falsa sensação de segurança.

No entanto, há algumas desvantagens em usar mensagens:

  • Complexidade operacional adicional – O sistema de mensagens é outro componente do sistema que deve ser instalado, configurado e operado. É essencial que o agente de mensagens esteja altamente disponível, caso contrário, a confiabilidade do sistema será afetada.
  • Complexidade da implementação da interação baseada em solicitação/resposta – A interação no estilo solicitação/resposta requer algum trabalho para ser implementada. Cada mensagem de solicitação deve conter um identificador de canal de resposta e um identificador de correlação. O serviço grava uma mensagem de resposta contendo o ID de correlação para o canal de resposta. O cliente usa o ID de correlação para corresponder a resposta com a solicitação. Geralmente é mais fácil usar um mecanismo IPC que suporte diretamente solicitação/resposta.

Agora que vimos como usar o IPC baseado em mensagens, vamos examinar o IPC baseado em solicitação/resposta.

IPC síncrono, solicitação/resposta

Ao usar um mecanismo IPC síncrono baseado em solicitação/resposta, um cliente envia uma solicitação a um serviço. O serviço processa a solicitação e envia uma resposta. Em muitos clientes, o thread que faz a solicitação fica bloqueado enquanto aguarda uma resposta. Outros clientes podem usar código de cliente assíncrono e orientado a eventos, que talvez seja encapsulado por Futures ou Rx Observables. No entanto, diferentemente do uso de mensagens, o cliente assume que a resposta chegará em tempo hábil. Há vários protocolos para escolher. Dois protocolos populares são REST e Thrift. Vamos primeiro dar uma olhada no REST.

DESCANSAR

Hoje em dia está na moda desenvolver APIs no estilo RESTful . REST é um mecanismo IPC que (quase sempre) usa HTTP. Um conceito-chave em REST é um recurso, que normalmente representa um objeto de negócios, como um Cliente ou Produto, ou uma coleção de objetos de negócios. REST usa verbos HTTP para manipular recursos, que são referenciados usando uma URL. Por exemplo, uma solicitação GET retorna a representação de um recurso, que pode estar no formato de um documento XML ou objeto JSON. Uma solicitação POST cria um novo recurso e uma solicitação PUT atualiza um recurso. Para citar Roy Fielding, o criador do REST:

O REST fornece um conjunto de restrições arquitetônicas que, quando aplicadas como um todo, enfatizam a escalabilidade das interações dos componentes, a generalidade das interfaces, a implantação independente dos componentes e os componentes intermediários para reduzir a latência da interação, reforçar a segurança e encapsular sistemas legados.

O diagrama a seguir mostra uma das maneiras pelas quais o aplicativo de chamada de táxi pode usar REST.


No aplicativo de chamada de táxi baseado em microsserviços, o smartphone do passageiro envia uma solicitação POST, que o microsserviço de gerenciamento de viagem converte em uma solicitação GET para o microsserviço de verificação de passageiros

O smartphone do passageiro solicita uma viagem fazendo uma solicitação POST ao recurso /trips do serviço de gerenciamento de viagens. Este serviço processa a solicitação enviando uma solicitação GET de informações sobre o passageiro para o serviço de Gerenciamento de Passageiros. Após verificar se o passageiro está autorizado a criar uma viagem, o serviço de Gerenciamento de Viagens cria a viagem e retorna um201 resposta ao smartphone.

Muitos desenvolvedores afirmam que suas APIs baseadas em HTTP são RESTful. No entanto, como Fielding descreve nesta postagem do blog , nem todos eles realmente são. Leonard Richardson (sem parentesco) define um modelo de maturidade muito útil para REST que consiste nos seguintes níveis.

  • Nível 0 – Clientes de uma API de nível 0 invocam o serviço fazendo solicitações HTTP POST para seu único ponto de extremidade de URL. Cada solicitação especifica a ação a ser executada, o alvo da ação (por exemplo, o objeto de negócios) e quaisquer parâmetros.
  • Nível 1 – Uma API de nível 1 suporta a ideia de recursos. Para executar uma ação em um recurso, um cliente faz uma solicitação POST que especifica a ação a ser executada e quaisquer parâmetros.
  • Nível 2 – Uma API de nível 2 usa verbos HTTP para executar ações: GET para recuperar, POST para criar e PUT para atualizar. Os parâmetros da consulta de solicitação e o corpo, se houver, especificam os parâmetros da ação. Isso permite que os serviços aproveitem a infraestrutura da web, como o cache para solicitações GET .
  • Nível 3 – O design de uma API de nível 3 é baseado no princípio terrivelmente denominado HATEOAS (Hypertext As The Engine Of Application State). A ideia básica é que a representação de um recurso retornado por uma solicitação GET contém links para executar as ações permitidas naquele recurso. Por exemplo, um cliente pode cancelar um pedido usando um link na representação do pedido retornada em resposta à solicitação GET enviada para recuperar o pedido. Os benefícios do HATEOAS incluem não ter mais que conectar URLs ao código do cliente. Outro benefício é que, como a representação de um recurso contém links para as ações permitidas, o cliente não precisa adivinhar quais ações podem ser executadas em um recurso em seu estado atual.

Existem inúmeros benefícios em usar um protocolo baseado em HTTP:

  • HTTP é simples e familiar.
  • Você pode testar uma API HTTP em um navegador usando uma extensão como o Postman ou na linha de comando usando curl (supondo que JSON ou algum outro formato de texto seja usado).
  • Ele oferece suporte direto à comunicação no estilo solicitação/resposta.
  • O HTTP é, obviamente, compatível com firewall.
  • Não requer um corretor intermediário, o que simplifica a arquitetura do sistema.

Existem algumas desvantagens em usar HTTP:

  • Ele suporta diretamente apenas o estilo de interação de solicitação/resposta. Você pode usar HTTP para notificações, mas o servidor deve sempre enviar uma resposta HTTP.
  • Como o cliente e o serviço se comunicam diretamente (sem um intermediário para armazenar mensagens em buffer), ambos devem estar em execução durante toda a troca.
  • O cliente deve saber a localização (ou seja, a URL) de cada instância de serviço. Conforme descrito no artigo anterior sobre o API Gateway , esse é um problema não trivial em um aplicativo moderno. Os clientes devem usar um mecanismo de descoberta de serviço para localizar instâncias de serviço.

A comunidade de desenvolvedores redescobriu recentemente o valor de uma linguagem de definição de interface para APIs RESTful. Existem algumas opções, incluindo RAML e Swagger . Alguns IDLs, como o Swagger, permitem que você defina o formato das mensagens de solicitação e resposta. Outros, como RAML, exigem que você use uma especificação separada, como JSON Schema . Além de descrever APIs, os IDLs normalmente têm ferramentas que geram stubs de cliente e esqueletos de servidor a partir de uma definição de interface.

Economia

O Apache Thrift é uma alternativa interessante ao REST. É uma estrutura para escrever clientes e servidores RPC entre linguagens. O Thrift fornece um IDL estilo C para definir suas APIs. Você usa o compilador Thrift para gerar stubs do lado do cliente e esqueletos do lado do servidor. O compilador gera código para uma variedade de linguagens, incluindo C++, Java, Python, PHP, Ruby, Erlang e Node.js.

Uma interface Thrift consiste em um ou mais serviços. Uma definição de serviço é análoga a uma interface Java. É uma coleção de métodos fortemente tipados. Os métodos de economia podem retornar um valor (possivelmente nulo) ou podem ser definidos como unidirecionais. Métodos que retornam um valor implementam o estilo de interação de solicitação/resposta. O cliente aguarda uma resposta e pode gerar uma exceção. Os métodos unidirecionais correspondem ao estilo de interação de notificação. O servidor não envia uma resposta.

O Thrift suporta vários formatos de mensagem: JSON, binário e binário compacto. O binário é mais eficiente que o JSON porque é mais rápido de decodificar. E, como o nome sugere, o binário compacto é um formato que economiza espaço. JSON é, obviamente, amigável ao ser humano e ao navegador. O Thrift também oferece uma escolha de protocolos de transporte, incluindo TCP e HTTP brutos. O TCP bruto provavelmente é mais eficiente que o HTTP. No entanto, o HTTP é amigável ao firewall, ao navegador e ao ser humano.

Formatos de mensagem

Agora que vimos HTTP e Thrift, vamos examinar a questão dos formatos de mensagem. Se estiver usando um sistema de mensagens ou REST, você poderá escolher o formato da mensagem. Outros mecanismos de IPC, como o Thrift, podem suportar apenas um pequeno número de formatos de mensagem, talvez apenas um. Em ambos os casos, é importante usar um formato de mensagem multilíngue. Mesmo que você esteja escrevendo seus microsserviços em uma única linguagem hoje, é provável que você use outras linguagens no futuro.

Existem dois tipos principais de formatos de mensagem: texto e binário. Exemplos de formatos baseados em texto incluem JSON e XML. Uma vantagem desses formatos é que eles não são apenas legíveis por humanos, mas também autodescritivos. Em JSON, os atributos de um objeto são representados por uma coleção de pares nome-valor. Da mesma forma, em XML os atributos são representados por elementos e valores nomeados. Isso permite que o consumidor de uma mensagem escolha os valores nos quais está interessado e ignore o resto. Consequentemente, pequenas alterações no formato da mensagem podem ser facilmente compatíveis com versões anteriores.

A estrutura dos documentos XML é especificada por um esquema XML . Com o tempo, a comunidade de desenvolvedores percebeu que o JSON também precisa de um mecanismo semelhante. Uma opção é usar o JSON Schema , seja de forma independente ou como parte de um IDL, como o Swagger.

Uma desvantagem de usar um formato de mensagem baseado em texto é que as mensagens tendem a ser prolixas, especialmente XML. Como as mensagens são autodescritivas, cada mensagem contém o nome dos atributos, além de seus valores. Outra desvantagem é a sobrecarga de análise de texto. Consequentemente, você pode considerar usar um formato binário.

Há vários formatos binários para escolher. Se você estiver usando o Thrift RPC, você pode usar o Thrift binário. Se você puder escolher o formato da mensagem, as opções populares incluem Protocol Buffers e Apache Avro . Ambos os formatos fornecem um IDL digitado para definir a estrutura das suas mensagens. Uma diferença, no entanto, é que os Protocol Buffers usam campos marcados, enquanto um consumidor Avro precisa conhecer o esquema para interpretar mensagens. Como resultado, a evolução da API é mais fácil com Protocol Buffers do que com Avro. Esta postagem do blog é uma excelente comparação entre Thrift, Protocol Buffers e Avro.

Resumo

Os microsserviços devem se comunicar usando um mecanismo de comunicação entre processos. Ao projetar como seus serviços se comunicarão, você precisa considerar várias questões: como os serviços interagem, como especificar a API para cada serviço, como evoluir as APIs e como lidar com falhas parciais. Existem dois tipos de mecanismos de IPC que os microsserviços podem usar: mensagens assíncronas e solicitação/resposta síncrona. No próximo artigo da série, veremos o problema da descoberta de serviços em uma arquitetura de microsserviços.

Editor – Esta série de artigos em sete partes está agora completa:

  1. Introdução aos Microsserviços
  2. Construindo Microsserviços: Usando um gateway de API
  3. Construindo Microsserviços: Comunicação entre processos em uma arquitetura de microsserviços (este artigo)
  4. Descoberta de serviços em uma arquitetura de microsserviços
  5. Gerenciamento de dados orientado a eventos para microsserviços
  6. Escolhendo uma estratégia de implantação de microsserviços
  7. Refatorando um monólito em microsserviços

Você também pode baixar o conjunto completo de artigos, além de informações sobre a implementação de microsserviços usando o NGINX Plus, como um e-book – Microsserviços: Do design à implantação .

O blogueiro convidado Chris Richardson é o fundador do CloudFoundry.com original, um dos primeiros Java PaaS (Plataforma como Serviço) para Amazon EC2. Agora, ele presta consultoria a organizações para melhorar a maneira como elas desenvolvem e implantam aplicativos. Ele também escreve regularmente sobre microsserviços em http://microservices.io .


"Esta postagem do blog pode fazer referência a produtos que não estão mais disponíveis e/ou não têm mais suporte. Para obter as informações mais atualizadas sobre os produtos e soluções F5 NGINX disponíveis, explore nossa família de produtos NGINX . O NGINX agora faz parte do F5. Todos os links anteriores do NGINX.com redirecionarão para conteúdo semelhante do NGINX no F5.com."