Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Dica
Esse conteúdo é um trecho do eBook, arquitetura de microsserviços do .NET para aplicativos .NET em contêineres, disponível em do .NET Docs ou como um PDF para download gratuito que pode ser lido offline.
Em uma arquitetura de microsserviços, cada microsserviço expõe um conjunto de pontos de extremidade (tipicamente) refinados. Esse fato pode afetar a comunicação cliente a microsserviço, conforme explicado nesta seção.
Comunicação direta entre cliente e microsserviço
Uma abordagem possível é usar uma arquitetura direta de comunicação cliente a microsserviço. Nessa abordagem, um aplicativo cliente pode fazer solicitações diretamente para alguns dos microsserviços, conforme mostrado na Figura 4-12.
Figura 4-12. Usando uma arquitetura direta de comunicação cliente a 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 entre os microsserviços. Em ambientes de produção, você pode ter um Controlador de Entrega de Aplicativos (ADC) como o Gateway de Aplicativo do Azure entre seus microsserviços e a Internet. Essa camada atua como uma camada transparente que não só executa o balanceamento de carga, mas protege seus serviços oferecendo terminação SSL. Essa abordagem melhora o desempenho de seus hosts ao transferir a terminação de SSL, que consome muita CPU, e outras funções de roteamento para o Gateway de Aplicações do Azure. De qualquer forma, um balanceador de carga e o ADC são transparentes do ponto de vista da arquitetura do aplicativo lógico.
Uma arquitetura direta de comunicação cliente a microsserviço pode ser boa o suficiente para um aplicativo pequeno 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 grandes e complexos baseados em microsserviços (por exemplo, ao lidar com dezenas de tipos de microsserviço) 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 com base 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?
Interagir 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. O ideal é que as respostas sejam agregadas com eficiência no lado do servidor. Essa abordagem reduz a latência, já que várias partes de dados voltam em paralelo e algumas interfaces do usuário podem mostrar dados assim que eles estão prontos.
- Como você pode lidar com questões de corte cruzado, como autorização, transformações de dados e expedição de solicitações dinâmicas?
A implementação de questões de segurança e de corte cruzado, como segurança e autorização em cada microsserviço, pode exigir esforços significativos de desenvolvimento. Uma abordagem possível é configurar esses serviços no host do Docker ou no cluster interno para restringir o acesso direto a eles a partir do ambiente externo e implementar essas preocupações transversais em um local centralizado, como um Gateway de API.
- 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 têm suporte em aplicativos cliente. Portanto, as solicitações devem ser executadas por meio de protocolos como HTTP/HTTPS e traduzidas para os outros protocolos posteriormente. Uma abordagem homem-no-meio 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 um aplicativo móvel podem ser diferentes das necessidades de um aplicativo 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 todos os dados na resposta que não são 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 de cliente para microsserviço
Em uma arquitetura de microsserviços, os aplicativos cliente geralmente precisam consumir funcionalidade de mais de um microsserviço. Caso esse consumo seja executado diretamente, o cliente precisará lidar com várias chamadas para os endpoints dos microsserviços. O que acontece quando o aplicativo evolui e novos microsserviços são introduzidos ou microsserviços existentes são atualizados? Se o seu aplicativo tiver muitos microsserviços, lidar com tantos endpoints 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 uma camada de indireção (Gateway) pode ser conveniente para aplicativos baseados em microsserviço. Se você não tiver Gateways de API, os aplicativos cliente deverão enviar solicitações diretamente para os microsserviços e isso gera problemas, como os seguintes problemas:
Acoplamento: sem o padrão de Gateway de API, 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 seguro o aplicativo poderá ser.
Preocupações transversais: cada microsserviço publicado deve lidar com preocupações como autorização e SSL. Em muitas situações, essas preocupações podem ser tratadas em uma única camada para que os microsserviços internos sejam simplificados.
Qual é o padrão do Gateway de API?
Ao projetar e criar aplicativos grandes ou complexos baseados em microsserviços com vários aplicativos cliente, uma boa abordagem a ser considerada pode ser um Gateway de API. Esse padrão é um serviço que fornece um ponto de entrada única para determinados grupos de microsserviços. É semelhante ao padrão Facade do design orientado a objetos, mas, nesse caso, faz parte de um sistema distribuído. O padrão de Gateway de API às vezes também é conhecido como BFF ("back-end para front-end"), porque ele é criado 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. Também pode fornecer outros recursos transversais, como autenticação, terminação SSL e cache.
A Figura 4-13 mostra como um Gateway de API personalizado pode se encaixar em uma arquitetura simplificada baseada em microsserviço com apenas alguns microsserviços.
Figura 4-13. Usando um Gateway de API implementado como um serviço personalizado
Os aplicativos se conectam a um único ponto de extremidade, o Gateway de API, configurado para encaminhar solicitações para microsserviços individuais. Neste exemplo, o Gateway de API seria implementado como um serviço WebHost ASP.NET Core personalizado em execução como um contêiner.
É importante destacar que, nesse diagrama, você estaria usando um único serviço de Gateway de API personalizado voltado para vários e diferentes aplicativos cliente. Esse fato pode ser um risco importante porque seu serviço de Gateway de API estará crescendo e evoluindo com base em muitos requisitos diferentes dos aplicativos cliente. Eventualmente, ele será sobrecarregado devido a essas diferentes necessidades e, na prática, pode ser semelhante a um aplicativo monolítico ou serviço monolítico. É por isso que é muito recomendável dividir o Gateway de API em vários serviços ou vários Gateways de API menores, um por tipo de fator de formulário de aplicativo cliente, por exemplo.
Você precisa ter cuidado ao implementar o padrão de Gateway de API. Normalmente, não é uma boa ideia ter um único Gateway de API agregando todos os microsserviços internos do seu aplicativo. Se isso acontecer, ele atuará como um agregador ou orquestrador monolítico e violará a autonomia do microsserviço acoplando 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 atuar como um único agregador para todos os microsserviços internos.
Ao dividir a camada do Gateway de API em vários Gateways de API, se o aplicativo tiver vários aplicativos cliente, isso poderá ser um fator fundamental ao identificar os vários tipos de Gateways de API, de modo que você possa ter uma fachada distinta para as necessidades de cada aplicativo cliente. Esse caso é um padrão chamado "Backend for Frontend" (BFF), em que cada Gateway de API pode fornecer uma API diferente personalizada para cada tipo de aplicativo cliente, possivelmente até mesmo com base no fator de formulário do cliente implementando um código de adaptador específico que, abaixo, chama vários microsserviços internos, conforme mostrado na imagem a seguir:
Figura 4-13.1. Usando vários Gateways de API personalizados
A Figura 4-13.1 mostra os Gateways de API segregados por tipo de cliente; um para clientes móveis e outro para clientes Web. Um aplicativo Web tradicional se conecta a um microsserviço MVC que usa o Gateway de API Web. O exemplo ilustra uma arquitetura simplificada com vários Gateways de API refinados. Nesse caso, os limites identificados para cada Gateway de API são baseados puramente no padrão "Backend for Frontend" (BFF), portanto, com base apenas na API necessária por aplicativo cliente. No entanto, em aplicativos maiores, você também deve ir além e criar outros Gateways de APIs com base nas fronteiras de negócios como um segundo ponto de partida de design.
Principais recursos no padrão de gateway para APIs
Um Gateway de API pode oferecer vários recursos. Dependendo do produto, ele pode oferecer recursos mais avançados ou mais simples, no entanto, os recursos mais importantes e fundamentais para qualquer Gateway de API são os seguintes padrões de design:
Proxy reverso ou roteamento de gateway. O API Gateway oferece um proxy reverso para redirecionar ou encaminhar solicitações (roteamento na camada 7, geralmente solicitações HTTP) para os endpoints 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 desacoplar os aplicativos cliente dos microsserviços, mas também é conveniente ao modernizar uma API monolítica, colocando o Gateway de API entre a API monolítica e os aplicativos cliente, então 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 Gateway de API, os aplicativos cliente não observarão se as APIs que estão sendo usadas forem 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 Gateway de API, os aplicativos cliente não serão afetados com nenhuma alteração de URI.
Para obter mais informações, consulte o padrão de roteamento do Gateway.
Solicitações de 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 Gateway de API que envia 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 o objetivo desse padrão de design é reduzir a conversa entre os aplicativos cliente e a API de back-end, que é especialmente importante para aplicativos remotos fora do datacenter em que os microsserviços residem, como aplicativos móveis ou solicitações provenientes de aplicativos SPA provenientes do JavaScript em navegadores remotos do cliente. Para aplicativos Web regulares que executam as solicitações no ambiente do servidor (como um aplicativo Web ASP.NET Core MVC), esse padrão não é tão importante quanto a latência é muito menor do que para aplicativos cliente remotos.
Dependendo do produto do Gateway de API 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 no escopo do Gateway de API, portanto, você define a agregação no código (ou seja, código C#):
Para obter mais informações, consulte o padrão de agregação do Gateway.
Interesses paralelos ou descarregamento de gateway. Dependendo dos recursos oferecidos por cada produto do Gateway de API, você pode delegar funções 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 todos os microsserviços internos, como a seguinte funcionalidade:
- Autenticação e autorização
- Integração de serviços de descoberta
- Cache de resposta
- Políticas de repetição, disjuntor e QoS
- Limitação de taxa
- Balanceamento de carga
- Registro em log, rastreamento, correlação
- Cabeçalhos, cadeias de caracteres de consulta e transformação de declarações
- Lista de IPs permitidos
Para obter mais informações, consulte o padrão de descarregamento do Gateway.
Usando produtos com recursos de API Gateway
Pode haver muitas mais preocupações transversais oferecidas pelos produtos de API Gateway, dependendo da implementação. Exploraremos aqui:
Gerenciamento de API do Azure
O Gerenciamento de API do Azure (conforme mostrado na Figura 4-14) não só resolve suas necessidades de Gateway de API, mas fornece recursos como coletar insights de suas APIs. Se você estiver usando uma solução de gerenciamento de API, um Gateway de API será apenas um componente dentro dessa solução de gerenciamento de API completa.
Figura 4-14. Usando o Gerenciamento de API do Azure para seu Gateway de API
O Gerenciamento de API do Azure resolve as necessidades do Gateway de API e do Gerenciamento, como registro em log, segurança, medição etc. Nesse caso, ao usar um produto como o Gerenciamento de API do Azure, o fato de você 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 um código C# personalizado que pode evoluir para um componente monolítico.
Os produtos de Gateway de API costumam atuar como um proxy reverso para comunicação de entrada, em que você também pode filtrar as APIs dos microsserviços internos e aplicar a autorização para as APIs publicadas nessa camada única.
Os insights disponíveis em um sistema de Gerenciamento de APIs ajudam você a entender como suas APIs estão sendo utilizadas e como elas estão desempenhando. Eles fazem essa atividade permitindo que você veja relatórios de análise quase em tempo real e identificando tendências que podem afetar seus negócios. Além disso, você pode ter logs sobre a atividade de solicitação e resposta para mais análises online e offline.
Com o Gerenciamento de API do Azure, você pode proteger suas APIs usando uma chave, um token e uma filtragem de IP. Esses recursos permitem impor cotas flexíveis e refinadas e limites de taxa, modificar a forma e o comportamento de suas APIs usando políticas e melhorar o desempenho com o cache de resposta.
Neste guia e no aplicativo de exemplo de referência (eShopOnContainers), a arquitetura é limitada a uma versão mais simples e personalizada de arquitetura em contêineres, com o objetivo de focar em contêineres independentes sem o uso de produtos PaaS, tais como o Gerenciamento de API do Azure. No entanto, para grandes aplicativos baseados em microsserviço 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.
Ocelote
O Ocelot é um Gateway de API leve, recomendado para abordagens mais simples. O Ocelot é um Gateway de API baseado em .NET Core de software livre, especialmente feito para arquiteturas de microsserviços que precisam de pontos unificados de entrada em seus sistemas. Ele é leve, rápido e escalonável e fornece roteamento e autenticação entre muitos outros recursos.
O principal motivo para escolher o Ocelot para o aplicativo de referência eShopOnContainers 2.0 é porque o Ocelot é um Gateway de API leve do .NET Core que você pode implantar no mesmo ambiente de implantação de aplicativo em que você está implantando seus microsserviços/contêineres, como um Host do Docker, Kubernetes etc. E como ele é baseado no .NET Core, ele é multiplataforma, permitindo que você implante no Linux ou no Windows.
Os diagramas anteriores que mostram gateways de API personalizados em execução em contêineres ilustram precisamente como você pode executar Ocelot tanto em um contêiner quanto em aplicações baseadas em microsserviços.
Além disso, existem muitos outros produtos no mercado que oferecem recursos de Gateways de API, 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 de explicação de padrões e arquitetura inicial, as próximas seções explicam como implementar gateways de API com o Ocelot.
Desvantagens do padrão de Gateway de API
A desvantagem mais importante é que, ao implementar um Gateway de API, você está acoplando essa camada com os microsserviços internos. Acoplamento como esse pode apresentar sérias dificuldades para seu aplicativo. Clemens Vaster, arquiteto na equipe do Barramento de Serviço do Azure, refere-se a essa possível dificuldade como "o novo ESB" na sessão "Mensagens e microsserviços" na GOTO 2016.
O uso de um Gateway de API de microsserviços cria um ponto único de falha adicional possível.
Um Gateway de API pode introduzir um tempo de resposta maior devido à chamada de rede adicional. No entanto, essa chamada extra geralmente tem menos impacto do que ter uma interface de cliente muito verbosa chamando diretamente os microsserviços internos.
Se não for dimensionado corretamente, o Gateway de API poderá se tornar um gargalo.
Um Gateway de API exigirá custo de desenvolvimento adicional e manutenção futura se incluir lógica personalizada e agregação de dados. Os desenvolvedores devem atualizar o Gateway de API para expor os endpoints 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 Gateway de API. No entanto, se o Gateway de API 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 poderá não se aplicar.
Se o Gateway de API for desenvolvido por uma única equipe, poderá haver um gargalo de desenvolvimento. Esse aspecto é outro motivo pelo qual uma abordagem melhor é ter vários Gateways de API refinados que respondem às diferentes necessidades do cliente. Você também pode separar o Gateway de API internamente em várias áreas ou camadas que pertencem às diferentes equipes que trabalham nos microsserviços internos.
Recursos adicionais
Chris Richardson. Padrão: Gateway de API/Back-end para Front-end
https://microservices.io/patterns/apigateway.htmlPadrão de Gateway de API
https://learn.microsoft.com/azure/architecture/microservices/gatewayPadrão de agregação e composição
https://microservices.io/patterns/data/api-composition.htmlGerenciamento de API do Azure
https://azure.microsoft.com/services/api-management/Udi Dahan. Composição orientada ao serviço
https://udidahan.com/2014/07/30/service-oriented-composition-with-video/Clemens Vasters. Mensagens e microsserviços no GOTO 2016 (vídeo)
https://www.youtube.com/watch?v=rXi5CLjIQ9kResumo sobre o Gateway de API (série de tutoriais do Gateway de API do ASP.NET Core)
https://www.pogsdotnet.com/2018/08/api-gateway-in-nutshell.html