Decodificando a Alta Disponibilidade de Microservices: Explorando Estratégias de Governança de API com Apache APISIX
March 29, 2024
Introdução
A arquitetura de microservices tornou-se a escolha mainstream para a arquitetura de TI atualmente. Sua flexibilidade e escalabilidade facilitam que as empresas lidem com requisitos de negócios em rápida mudança. No entanto, garantir a alta disponibilidade dos microservices tornou-se uma questão-chave no design arquitetônico. Nesse contexto, as três estratégias principais na governança de serviços de API — limitação de taxa, circuit breaker e degradação — são particularmente importantes.
Como um componente essencial na arquitetura de microservices, o gateway de API desempenha um papel crucial na governança de serviços. O Apache APISIX, como um gateway de API cloud-native de nova geração, não apenas possui capacidades de alto desempenho e segurança, mas também oferece funcionalidades ricas de gerenciamento de tráfego. Na discussão a seguir, exploraremos a "abordagem tripla" da governança de serviços de API e forneceremos insights detalhados sobre como aplicar essas estratégias no APISIX para garantir a alta disponibilidade dos nossos serviços.
Estratégias de Governança de API
Limitação de Taxa
A limitação de taxa, como o nome sugere, é um mecanismo restritivo implementado no tráfego. Seu princípio central é evitar a sobrecarga ou até mesmo a queda do sistema causada por tráfego excessivo. O conceito fundamental reside em regular o volume de solicitações dentro de intervalos de tempo específicos, permitindo que apenas solicitações que atendam a certas restrições acessem o sistema, garantindo assim a operação estável dos microservices e de todo o sistema. Em cenários da vida real, o conceito de limitação de taxa também é evidente. Por exemplo, durante os horários de pico nas estações de metrô, vários portões de acesso são configurados para verificações de segurança, orientando filas ordenadas e suaves.
A limitação de taxa pode ser implementada de várias maneiras, incluindo:
-
Baseado na contagem de solicitações: Rastrear o número de solicitações dentro de cada período de tempo e limitá-las a um certo limite. Por exemplo, processar no máximo 100 solicitações por segundo.
-
Baseado na frequência de solicitações: Restringir a frequência de solicitações por cliente ou endereço IP para evitar um número excessivo de solicitações. Por exemplo, permitir no máximo 10 solicitações por minuto.
-
Baseado na contagem de conexões: Limitar o número de conexões simultâneas estabelecidas para evitar o consumo excessivo de recursos do sistema. Por exemplo, permitir no máximo 100 conexões simultâneas.
Diferentes estratégias de limitação de taxa nos permitem atender a vários requisitos de cenários. Por exemplo, para recursos de API valiosos, podemos limitar o número de solicitações a 10 por minuto. Ou, para melhorar a disponibilidade do serviço, podemos limitar o número de solicitações simultâneas para reduzir o tempo de resposta do serviço, entre outros cenários. A implementação adequada dessas estratégias de limitação de taxa pode ajudar a garantir a operação normal dos serviços sob alta concorrência e picos repentinos de tráfego.
Circuit Breaker
Em uma arquitetura de microservices, pode haver situações em que os serviços se chamam mutuamente. Uma vez que um serviço falha, isso pode afetar outros serviços, ou até mesmo levar ao colapso de todo o sistema, um fenômeno vividamente chamado de "falha em cascata" ou "efeito avalanche". O mecanismo de circuit breaker, como uma medida protetora contra falhas em cascata em microservices, é usado para prevenir a propagação de falhas. Quando um microservice apresenta anormalidades ou atrasos, o circuit breaker será acionado rapidamente, bloqueando temporariamente as solicitações para esse serviço, garantindo assim que a estabilidade de todo o sistema não seja comprometida.
O princípio central do mecanismo de circuit breaker reside no monitoramento em tempo real do tempo de resposta do serviço ou das taxas de erro. Uma vez que essas métricas excedam os limites pré-definidos, o circuit breaker é acionado automaticamente, interrompendo rapidamente as solicitações para o serviço com falha até que ele retorne à operação normal. Após a estabilização do serviço, o circuit breaker fecha automaticamente, retomando o acesso ao serviço. Esse mecanismo é semelhante a um resistor em um circuito elétrico. Quando a tensão excede sua faixa de tolerância, o resistor desconecta automaticamente o circuito para evitar que a corrente excessiva danifique outros componentes eletrônicos. Após inspecionar e reparar o circuito, o resistor fecha novamente, e o circuito retoma a operação normal.
Ao introduzir mecanismos de circuit breaker, a arquitetura de microservices pode lidar melhor com potenciais problemas de falha em cascata decorrentes de chamadas mútuas de serviços, garantindo a estabilidade e confiabilidade do sistema, especialmente em cenários de alta pressão.
Degradação
A degradação, como uma estratégia eficaz para lidar com cargas elevadas do sistema, envolve desabilitar temporariamente algumas funções não críticas ou reduzir moderadamente a qualidade de certos serviços para garantir a operação estável do sistema como um todo. Na arquitetura de microservices, a aplicação de mecanismos de degradação pode proteger inteligentemente algumas funções não essenciais ou temporariamente dispensáveis, garantindo assim a operação contínua e estável das funções principais. Por exemplo, em um aplicativo de videoconferência, quando a largura de banda da rede é limitada, podemos reduzir a qualidade de transmissão de vídeo ou desabilitar temporariamente a funcionalidade de vídeo para garantir chamadas de áudio claras e estáveis, atendendo assim às necessidades básicas de comunicação da reunião.
Estratégias comuns incluem:
-
Degradação de função: Fechar temporariamente ou restringir o acesso a certas funções para garantir a operação normal dos serviços principais. Por exemplo, um aplicativo de mídia social pode desabilitar temporariamente as funções de "curtir" ou "comentar" durante os horários de pico para garantir que os usuários possam navegar no conteúdo normalmente.
-
Degradação de qualidade: Durante cargas elevadas do sistema, reduzir os requisitos de qualidade de certos serviços ou funções. Por exemplo, como mencionado anteriormente, reduzir a clareza do vídeo ou a taxa de quadros para garantir uma comunicação suave.
Limitação de Taxa, Circuit Breaker e Degradação no APISIX
Como podemos utilizar as três principais estratégias mencionadas habilitadas no APISIX para melhorar a alta disponibilidade dos microservices? Abaixo estão apenas alguns exemplos comuns de aplicação para ilustração.
Limitação de Taxa com o Plugin limit-count
O APISIX fornece vários plugins de gerenciamento de tráfego integrados, como limit-count
, limit-req
e limit-conn
. Dependendo das necessidades reais, podemos escolher o método apropriado para o controle de tráfego. Tomando o plugin limit-count
como exemplo, ele restringe o número total de solicitações dentro de um intervalo de tempo específico e retorna a contagem restante de solicitações no cabeçalho HTTP.
curl -i http://127.0.0.1:9080/apisix/admin/routes/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri": "/get",
"plugins": {
"limit-count": {
"count": 3,
"time_window": 60,
"rejected_code": 429,
"key_type": "var",
"key": "remote_addr"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
Circuit Breaker com o Plugin api-breaker
O plugin api-breaker
no APISIX aciona automaticamente mecanismos de circuit breaker com base em limites pré-definidos para prevenir falhas em cascata. Por exemplo, ele pode iniciar o circuit breaker quando os serviços upstream retornam 3 códigos de status 500 ou 503 consecutivos e retomar o acesso quando um código de status 200 é recebido.
curl "http://127.0.0.1:9180/apisix/admin/routes/1" \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"plugins": {
"api-breaker": {
"break_response_code": 502,
"unhealthy": {
"http_statuses": [500, 503],
"failures": 3
},
"healthy": {
"http_statuses": [200],
"successes": 1
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
},
"uri": "/get",
}'
Degradação com o Plugin fault-injection
Os plugins fault-injection
e mocking
do APISIX suportam a configuração de estratégias de degradação para desabilitar temporariamente certas funções ou retornar diretamente dados pré-definidos durante cargas elevadas do sistema, garantindo a estabilidade do sistema. Por exemplo, o plugin fault-injection
pode retornar diretamente códigos de status HTTP e valores de corpo especificados para os clientes.
curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"plugins": {
"fault-injection": {
"abort": {
"http_status": 200,
"body": "Fault Injection!"
}
}
},
"upstream": {
"nodes": {
"httpbin.org:80": 1
},
"type": "roundrobin"
},
"uri": "/get"
}'
Conclusão
A limitação de taxa, o circuit breaker e a degradação, como medidas cruciais de governança de serviços na arquitetura de microservices, desempenham um papel insubstituível na melhoria da alta disponibilidade dos microservices. Eles atuam como escudos sólidos, defendendo a arquitetura de microservices contra vários riscos e desafios potenciais. Diante de diversos cenários de negócios, devemos aplicar essas medidas de forma flexível e cautelosa para garantir que a estabilidade e confiabilidade da arquitetura de microservices sejam protegidas de maneira ideal.