Partilhar via


O padrão de gateway de API versus a comunicação direta cliente-microsserviço

Gorjeta

Este conteúdo é um trecho do eBook, .NET Microservices Architecture for Containerized .NET Applications, disponível no .NET Docs ou como um PDF para download gratuito que pode ser lido offline.

.NET Microservices Architecture for Containerized .NET Applications eBook cover thumbnail.

Em uma arquitetura de microsserviços, cada microsserviço expõe um conjunto de pontos de extremidade (normalmente) refinados. Esse fato pode afetar a comunicação cliente-microsserviço, conforme explicado nesta seção.

Comunicação direta cliente-microsserviço

Uma abordagem possível é usar uma arquitetura de comunicação direta cliente-microsserviço. Nessa abordagem, um aplicativo cliente pode fazer solicitações diretamente para alguns dos microsserviços, como mostra a Figura 4-12.

Diagram showing client-to-microservice communication architecture.

Figura 4-12. Usando uma arquitetura de comunicação direta cliente-microsserviço

Nessa abordagem, cada microsserviço tem um ponto de extremidade público, às vezes com uma porta TCP diferente para cada microsserviço. Um exemplo de uma URL para um serviço específico pode ser a seguinte URL no Azure:

http://eshoponcontainers.westus.cloudapp.azure.com:88/

Em um ambiente de produção baseado em um cluster, essa URL seria mapeada para o balanceador de carga usado no cluster, que, por sua vez, distribui as solicitações pelos microsserviços. Em ambientes de produção, você pode ter um Application Delivery Controller (ADC) como o Azure Application Gateway entre seus microsserviços e a Internet. Essa camada atua como uma camada transparente que não apenas executa o balanceamento de carga, mas protege seus serviços oferecendo terminação SSL. Essa abordagem melhora a carga de seus hosts descarregando a terminação SSL com uso intensivo de CPU e outras tarefas de roteamento para o Gateway de Aplicativo do Azure. Em qualquer caso, um balanceador de carga e o ADC são transparentes do ponto de vista da arquitetura lógica do aplicativo.

Uma arquitetura de comunicação direta cliente-microsserviço pode ser boa o suficiente para um pequeno aplicativo baseado em microsserviço, especialmente se o aplicativo cliente for um aplicativo Web do lado do servidor, como um aplicativo MVC ASP.NET. No entanto, quando você cria aplicativos baseados em microsserviços grandes e complexos (por exemplo, ao lidar com dezenas de tipos de microsserviços), e especialmente quando os aplicativos cliente são aplicativos móveis remotos ou aplicativos Web SPA, essa abordagem enfrenta alguns problemas.

Considere as seguintes perguntas ao desenvolver um aplicativo grande baseado em microsserviços:

  • Como os aplicativos cliente podem minimizar o número de solicitações para o back-end e reduzir a comunicação tagarela para vários microsserviços?

A interação com vários microsserviços para criar uma única tela de interface do usuário aumenta o número de viagens de ida e volta pela Internet. Essa abordagem aumenta a latência e a complexidade no lado da interface do usuário. Idealmente, as respostas devem ser agregadas de forma eficiente no lado do servidor. Essa abordagem reduz a latência, uma vez que vários dados voltam em paralelo e algumas interfaces do usuário podem mostrar dados assim que estiverem prontos.

  • Como você pode lidar com preocupações transversais, como autorização, transformações de dados e despacho dinâmico de solicitações?

A implementação de segurança e preocupações transversais, como segurança e autorização, em cada microsserviço pode exigir um esforço de desenvolvimento significativo. Uma abordagem possível é ter esses serviços dentro do host do Docker ou cluster interno para restringir o acesso direto a eles do lado de fora e implementar essas preocupações transversais em um local centralizado, como um API Gateway.

  • Como os aplicativos cliente podem se comunicar com serviços que usam protocolos não amigáveis à Internet?

Os protocolos usados no lado do servidor (como AMQP ou protocolos binários) não são suportados em aplicativos cliente. Portanto, as solicitações devem ser realizadas através de protocolos como HTTP/HTTPS e traduzidas para os outros protocolos posteriormente. Uma abordagem "man-in-the-middle " pode ajudar nesta situação.

  • Como você pode moldar uma fachada especialmente feita para aplicativos móveis?

A API de vários microsserviços pode não ser bem projetada para as necessidades de diferentes aplicativos cliente. Por exemplo, as necessidades de uma aplicação móvel podem ser diferentes das necessidades de uma aplicação Web. Para aplicativos móveis, talvez seja necessário otimizar ainda mais para que as respostas de dados possam ser mais eficientes. Você pode fazer essa funcionalidade agregando dados de vários microsserviços e retornando um único conjunto de dados e, às vezes, eliminando quaisquer dados na resposta que não sejam necessários para o aplicativo móvel. E, claro, você pode compactar esses dados. Novamente, uma fachada ou API entre o aplicativo móvel e os microsserviços pode ser conveniente para esse cenário.

Por que considerar gateways de API em vez de comunicação direta cliente-microsserviço

Em uma arquitetura de microsserviços, os aplicativos cliente geralmente precisam consumir funcionalidade de mais de um microsserviço. Se esse consumo for realizado diretamente, o cliente precisará lidar com várias chamadas para pontos de extremidade de microsserviço. O que acontece quando o aplicativo evolui e novos microsserviços são introduzidos ou microsserviços existentes são atualizados? Se seu aplicativo tiver muitos microsserviços, lidar com tantos pontos de extremidade dos aplicativos cliente pode ser um pesadelo. Como o aplicativo cliente seria acoplado a esses pontos de extremidade internos, a evolução dos microsserviços no futuro pode causar alto impacto para os aplicativos cliente.

Portanto, ter um nível intermediário ou camada de indirection (Gateway) pode ser conveniente para aplicativos baseados em microsserviços. Se você não tiver gateways de API, os aplicativos cliente deverão enviar solicitações diretamente para os microsserviços e isso levantará problemas, como os seguintes problemas:

  • Acoplamento: Sem o padrão API Gateway, os aplicativos cliente são acoplados aos microsserviços internos. Os aplicativos cliente precisam saber como as várias áreas do aplicativo são decompostas em microsserviços. Ao evoluir e refatorar os microsserviços internos, essas ações afetam a manutenção porque causam alterações significativas nos aplicativos cliente devido à referência direta aos microsserviços internos dos aplicativos cliente. Os aplicativos cliente precisam ser atualizados com frequência, tornando a solução mais difícil de evoluir.

  • Muitas viagens de ida e volta: uma única página/tela no aplicativo cliente pode exigir várias chamadas para vários serviços. Essa abordagem pode resultar em várias viagens de ida e volta de rede entre o cliente e o servidor, adicionando latência significativa. A agregação tratada em um nível intermediário pode melhorar o desempenho e a experiência do usuário para o aplicativo cliente.

  • Problemas de segurança: sem um gateway, todos os microsserviços devem ser expostos ao "mundo externo", tornando a superfície de ataque maior do que se você ocultar microsserviços internos que não são usados diretamente pelos aplicativos cliente. Quanto menor for a superfície de ataque, mais segura poderá ser a sua aplicação.

  • Preocupações transversais: cada microsserviço publicado publicamente deve lidar com preocupações como autorização e SSL. Em muitas situações, essas preocupações podem ser tratadas em uma única camada, de modo que os microsserviços internos sejam simplificados.

O que é o padrão API Gateway?

Quando você projeta e cria aplicativos baseados em microsserviços grandes ou complexos com vários aplicativos cliente, uma boa abordagem a ser considerada pode ser um API Gateway. Esse padrão é um serviço que fornece um ponto de entrada único para determinados grupos de microsserviços. É semelhante ao padrão Facade do design orientado a objetos, mas, neste caso, faz parte de um sistema distribuído. O padrão API Gateway também é às vezes conhecido como "backend para frontend" (BFF) porque você o cria pensando nas necessidades do aplicativo cliente.

Portanto, o gateway de API fica entre os aplicativos cliente e os microsserviços. Ele atua como um proxy reverso, roteando solicitações de clientes para serviços. Ele também pode fornecer outros recursos transversais, como autenticação, terminação SSL e cache.

A Figura 4-13 mostra como um API Gateway personalizado pode se encaixar em uma arquitetura simplificada baseada em microsserviços com apenas alguns microsserviços.

Diagram showing an API Gateway implemented as a custom service.

Figura 4-13. Usando um API Gateway implementado como um serviço personalizado

Os aplicativos se conectam a um único ponto de extremidade, o API Gateway, que é configurado para encaminhar solicitações para microsserviços individuais. Neste exemplo, o API Gateway seria implementado como um serviço personalizado ASP.NET Core WebHost em execução como um contêiner.

É importante destacar que, nesse diagrama, você estaria usando um único serviço personalizado do API Gateway voltado para vários e diferentes aplicativos cliente. Esse fato pode ser um risco importante porque seu serviço API Gateway estará crescendo e evoluindo com base em muitos requisitos diferentes dos aplicativos cliente. Eventualmente, ele será inchado por causa dessas diferentes necessidades e, efetivamente, pode ser semelhante a um aplicativo monolítico ou serviço monolítico. É por isso que é muito recomendável dividir o API Gateway em vários serviços ou vários Gateways de API menores, um por tipo de fator de forma de aplicativo cliente, por exemplo.

Você precisa ter cuidado ao implementar o padrão API Gateway. Normalmente, não é uma boa ideia ter um único API Gateway agregando todos os microsserviços internos do seu aplicativo. Se o fizer, atua como um agregador ou orquestrador monolítico e viola a autonomia do microsserviço ao acoplar todos os microsserviços.

Portanto, os Gateways de API devem ser segregados com base nos limites de negócios e nos aplicativos cliente e não agir como um único agregador para todos os microsserviços internos.

Ao dividir a camada do API Gateway em vários API Gateways, se seu aplicativo tiver vários aplicativos cliente, isso pode ser um pivô primário ao identificar os vários tipos de API Gateways, para que você possa ter uma fachada diferente para as necessidades de cada aplicativo cliente. Este caso é um padrão chamado "Backend for Frontend" (BFF) onde cada API Gateway pode fornecer uma API diferente adaptada para cada tipo de aplicativo cliente, possivelmente até mesmo com base no fator de forma do cliente, implementando código de adaptador específico que abaixo chama vários microsserviços internos, conforme mostrado na imagem a seguir:

Diagram showing multiple custom API Gateways.

Figura 4-13.1. Usando vários gateways de API personalizados

A Figura 4-13.1 mostra gateways de API segregados por tipo de cliente; um para clientes móveis e um para clientes web. Um aplicativo Web tradicional se conecta a um microsserviço MVC que usa o Web API Gateway. O exemplo descreve uma arquitetura simplificada com vários Gateways de API refinados. Nesse caso, os limites identificados para cada API Gateway são baseados puramente no padrão "Backend for Frontend" (BFF), portanto, baseado apenas na API necessária por aplicativo cliente. Mas em aplicativos maiores, você também deve ir além e criar outros API Gateways com base nos limites de negócios como um segundo pivô de design.

Principais recursos no padrão API Gateway

Um API Gateway pode oferecer vários recursos. Dependendo do produto, ele pode oferecer recursos mais ricos ou mais simples, no entanto, os recursos mais importantes e fundamentais para qualquer API Gateway são os seguintes padrões de design:

Proxy reverso ou roteamento de gateway. O API Gateway oferece um proxy reverso para redirecionar ou rotear solicitações (roteamento de camada 7, geralmente solicitações HTTP) para os pontos de extremidade dos microsserviços internos. O gateway fornece um único ponto de extremidade ou URL para os aplicativos cliente e, em seguida, mapeia internamente as solicitações para um grupo de microsserviços internos. Esse recurso de roteamento ajuda a separar os aplicativos cliente dos microsserviços, mas também é conveniente ao modernizar uma API monolítica colocando o API Gateway entre a API monolítica e os aplicativos cliente e, em seguida, você pode adicionar novas APIs como novos microsserviços enquanto ainda usa a API monolítica herdada até que ela seja dividida em muitos microsserviços no futuro. Devido ao API Gateway, os aplicativos cliente não perceberão se as APIs que estão sendo usadas são implementadas como microsserviços internos ou uma API monolítica e, mais importante, ao evoluir e refatorar a API monolítica em microsserviços, graças ao roteamento do API Gateway, os aplicativos cliente não serão afetados por nenhuma alteração de URI.

Para obter mais informações, consulte Padrão de roteamento de gateway.

Solicita agregação. Como parte do padrão de gateway, você pode agregar várias solicitações de cliente (geralmente solicitações HTTP) direcionadas a vários microsserviços internos em uma única solicitação de cliente. Esse padrão é especialmente conveniente quando uma página/tela do cliente precisa de informações de vários microsserviços. Com essa abordagem, o aplicativo cliente envia uma única solicitação para o API Gateway que despacha várias solicitações para os microsserviços internos e, em seguida, agrega os resultados e envia tudo de volta para o aplicativo cliente. O principal benefício e objetivo desse padrão de design é reduzir a conversação entre os aplicativos cliente e a API de back-end, o que é especialmente importante para aplicativos remotos fora do datacenter onde os microsserviços vivem, como aplicativos móveis ou solicitações provenientes de aplicativos SPA que vêm do JavaScript em navegadores remotos cliente. Para aplicativos Web regulares que executam as solicitações no ambiente de servidor (como um aplicativo Web MVC ASP.NET Core), esse padrão não é tão importante, pois a latência é muito menor do que para aplicativos cliente remotos.

Dependendo do produto API Gateway que você usa, ele pode ser capaz de executar essa agregação. No entanto, em muitos casos, é mais flexível criar microsserviços de agregação sob o escopo do API Gateway, para que você defina a agregação no código (ou seja, código C#):

Para obter mais informações, consulte Padrão de agregação de gateway.

Preocupações transversais ou descarregamento de gateway. Dependendo dos recursos oferecidos por cada produto API Gateway, você pode descarregar a funcionalidade de microsserviços individuais para o gateway, o que simplifica a implementação de cada microsserviço consolidando preocupações transversais em uma camada. Essa abordagem é especialmente conveniente para recursos especializados que podem ser complexos de implementar corretamente em cada microsserviço interno, como a seguinte funcionalidade:

  • Autenticação e autorização
  • Integração de descoberta de serviço
  • Cache de resposta
  • Políticas de repetição, disjuntor e QoS
  • Limitação e limitação da taxa
  • Balanceamento de carga
  • Registo, rastreio, correlação
  • Cabeçalhos, cadeias de caracteres de consulta e transformação de declarações
  • Lista de permissões de IP

Para obter mais informações, consulte Padrão de descarregamento de gateway.

Usando produtos com recursos do API Gateway

Pode haver muito mais preocupações transversais oferecidas pelos produtos API Gateways, dependendo de cada implementação. Vamos explorar aqui:

API Management do Azure

O Gerenciamento de API do Azure (conforme mostrado na Figura 4-14) não apenas resolve suas necessidades do API Gateway, mas também fornece recursos como a coleta de informações de suas APIs. Se você estiver usando uma solução de gerenciamento de API, um API Gateway será apenas um componente dentro dessa solução completa de gerenciamento de API.

Diagram showing how to use Azure API Management as your API gateway.

Figura 4-14. Usando o Gerenciamento de API do Azure para seu Gateway de API

O Gerenciamento de API do Azure resolve suas necessidades de Gateway de API e Gerenciamento, como registro, segurança, monitoramento, etc. Nesse caso, ao usar um produto como o Gerenciamento de API do Azure, o fato de que você pode ter um único Gateway de API não é tão arriscado porque esses tipos de Gateways de API são "mais finos", o que significa que você não implementa código C# personalizado que poderia evoluir para um componente monolítico.

Os produtos API Gateway geralmente agem como um proxy reverso para comunicação de entrada, onde você também pode filtrar as APIs dos microsserviços internos e aplicar autorização às APIs publicadas nessa única camada.

Os insights disponíveis de um sistema de gerenciamento de API ajudam você a entender como suas APIs estão sendo usadas e como elas estão funcionando. Eles fazem essa atividade permitindo que você visualize relatórios analíticos quase em tempo real e identifique tendências que podem afetar seus negócios. Além disso, você pode ter logs sobre a atividade de solicitação e resposta para análise on-line e off-line adicional.

Com o Gerenciamento de API do Azure, você pode proteger suas APIs usando uma chave, um token e filtragem de IP. Esses recursos permitem que você imponha cotas e limites de taxa flexíveis e refinados, modifique a forma e o comportamento de suas APIs usando políticas e melhore o desempenho com cache de resposta.

Neste guia e no aplicativo de exemplo de referência (eShopOnContainers), a arquitetura é limitada a uma arquitetura conteinerizada mais simples e personalizada para se concentrar em contêineres simples sem usar produtos PaaS como o Gerenciamento de API do Azure. Mas para grandes aplicativos baseados em microsserviços que são implantados no Microsoft Azure, recomendamos que você avalie o Gerenciamento de API do Azure como a base para seus Gateways de API em produção.

Jaguatirica

Ocelot é um API Gateway leve, recomendado para abordagens mais simples. Ocelot é um Open Source .NET Core baseado em API Gateway especialmente feito para arquiteturas de microsserviços que precisam de pontos de entrada unificados em seus sistemas. É leve, rápido e escalável e fornece roteamento e autenticação, entre muitos outros recursos.

A principal razão para escolher Ocelot para o aplicativo de referência eShopOnContainers 2.0 é porque Ocelot é um .NET Core leve API Gateway que você pode implantar no mesmo ambiente de implantação de aplicativo onde você está implantando seus microsserviços/contêineres, como um host Docker, Kubernetes, etc. E como é baseado no .NET Core, é multiplataforma, permitindo que você implante no Linux ou Windows.

Os diagramas anteriores mostrando Gateways de API personalizados em execução em contêineres são precisamente como você também pode executar Ocelot em um contêiner e aplicativo baseado em microsserviço.

Além disso, existem muitos outros produtos no mercado que oferecem recursos de API Gateways, como Apigee, Kong, MuleSoft, WSO2 e outros produtos como Linkerd e Istio para recursos de controlador de entrada de malha de serviço.

Após as seções iniciais de explicação de arquitetura e padrões, as próximas seções explicam como implementar gateways de API com Ocelot.

Desvantagens do padrão API Gateway

  • A desvantagem mais importante é que, ao implementar um API Gateway, você está acoplando essa camada com os microsserviços internos. Um acoplamento como este pode introduzir sérias dificuldades para a sua aplicação. Clemens Vaster, arquiteto da equipe do Barramento de Serviço do Azure, refere-se a essa dificuldade potencial como "o novo ESB" na sessão "Mensagens e Microsserviços" no GOTO 2016.

  • O uso de um gateway de API de microsserviços cria um possível ponto único adicional de falha.

  • Um API Gateway pode introduzir maior tempo de resposta devido à chamada de rede adicional. No entanto, essa chamada extra geralmente tem menos impacto do que ter uma interface de cliente muito tagarela chamando diretamente os microsserviços internos.

  • Se não for dimensionado corretamente, o API Gateway pode se tornar um gargalo.

  • Um API Gateway requer custo de desenvolvimento adicional e manutenção futura se incluir lógica personalizada e agregação de dados. Os desenvolvedores devem atualizar o API Gateway para expor os pontos de extremidade de cada microsserviço. Além disso, as alterações de implementação nos microsserviços internos podem causar alterações de código no nível do API Gateway. No entanto, se o API Gateway estiver apenas aplicando segurança, registro em log e controle de versão (como ao usar o Gerenciamento de API do Azure), esse custo de desenvolvimento adicional pode não se aplicar.

  • Se o API Gateway for desenvolvido por uma única equipe, pode haver um gargalo de desenvolvimento. Esse aspeto é outra razão pela qual uma abordagem melhor é ter vários API Gateways refinados que respondem às diferentes necessidades do cliente. Você também pode segregar o API Gateway internamente em várias áreas ou camadas que pertencem às diferentes equipes que trabalham nos microsserviços internos.

Recursos adicionais