Estratégias para tratar falhas parciais

Dica

Esse conteúdo é um trecho do eBook da Arquitetura de Microsserviços do .NET para os Aplicativos .NET em Contêineres, 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.

Para lidar com falhas parciais, use uma das estratégias descritas aqui.

Usar a comunicação assíncrona (por exemplo, comunicação baseada em mensagens) entre microsserviços internos. É altamente recomendado não criar cadeias longas de chamadas HTTP síncronas entre os microsserviços internos, porque esse design incorreto poderá se tornar a principal causa de interrupções incorretas. Pelo contrário, exceto pelas comunicações de front-end entre os aplicativos cliente e o primeiro nível de microsserviços ou Gateways de API refinados, é recomendado usar apenas a comunicação assíncrona (com base em mensagem) uma vez após o ciclo inicial de resposta/solicitação, entre os microsserviços internos. Consistência eventual e arquiteturas orientadas a eventos ajudarão a minimizar os efeitos de ondulação. Essas abordagens impõem um nível mais alto de autonomia do microsserviço e, portanto, previnem contra o problema observado aqui.

Usar novas tentativas com retirada exponencial. Essa técnica ajuda a evitar falhas curtas e intermitentes executando novas tentativas de chamada um determinado número de vezes, caso o serviço não tivesse estado disponível apenas por um curto período de tempo. Isso pode ocorrer devido a problemas de rede intermitentes ou quando um microsserviço/contêiner é movido para um nó diferente em um cluster. No entanto, se essas novas tentativas não foram criadas corretamente com disjuntores, os efeitos de ondulação poderão ser agravados e, em último caso, poderá até haver uma DoS (Negação de Serviço).

Solução alternativa para tempos limite de rede. Em geral, os clientes devem ser criados para não serem bloqueados indefinidamente e para sempre usar tempos limite ao aguardar uma resposta. Usar tempos limite garante que os recursos nunca fiquem bloqueados indefinidamente.

Usar o padrão de disjuntor. Nessa abordagem, o processo do cliente rastreia o número de solicitações com falha. Se a taxa de erro exceder um limite configurado, um "disjuntor" viajará para que outras tentativas falhem imediatamente. (Se um grande número de solicitações estiver falhando, isso sugere que o serviço está indisponível e que o envio de solicitações é inútil.) Após um período de tempo limite, o cliente deverá tentar novamente e, se as novas solicitações forem bem-sucedidas, fechar o disjuntor.

Fornecer fallbacks. Nessa abordagem, o processo de cliente executa a lógica de fallback quando uma solicitação falha, como retornar dados armazenados em cache ou um valor padrão. Essa é uma abordagem adequada para consultas e é mais complexa para atualizações ou comandos.

Limitar o número de solicitações na fila. Os clientes também devem impor um limite superior no número de solicitações pendentes que um microsserviço cliente pode enviar para um serviço específico. Se o limite for atingido, provavelmente será ineficaz fazer mais solicitações. As tentativas falharão imediatamente. Em termos de implementação, a política Isolamento do bulkhead da Polly pode ser usada para atender a esse requisito. Essa abordagem é essencialmente uma restrição de paralelização com SemaphoreSlim como a implementação. Ela também permite uma "fila" fora do bulkhead. É possível lançar proativamente uma carga excessiva mesmo antes da execução (por exemplo, devido à capacidade ser considerada cheia). Isso torna sua resposta a determinados cenários de falha mais rápida do que um disjuntor seria, uma vez que o disjuntor aguarda as falhas. O objeto BulkheadPolicy na Polly expõe se o bulkhead e a fila estão cheios e oferece eventos em estouro, portanto, ele também pode ser usado para permitir a escala horizontal automatizada.

Recursos adicionais