Tratamento de Falhas com .NET + Polly: implementando o padrão Circuit Breaker

Renato Groffe
4 min readJul 19, 2021

--

A utilização da biblioteca Polly para a implementação de um tratamento de falhas mais inteligente em .NET já foi abordada diversas vezes neste blog:

.NET 5 + JWT + Polly + Refit: consumindo APIs seguras com simplicidade e resiliência

.NET 5 + Polly: melhorando o tratamento de falhas em exemplos práticos

Em uma live recente no Canal .NET retomei este assunto, trazendo desta vez um exemplo de implementação do pattern conhecido como Circuit Breaker:

Bastante frequente em arquiteturas baseadas em Microsserviços, este padrão envolve o uso de um objeto também chamado de Circuit Breaker:

  • O Circuit Breaker inicia com o status Closed (Fechado), sendo empregado na execução de código de forma protegida e monitorando eventuais falhas que possam ocorrer;
  • Quando o número de falhas atingir um certo limite dentro de um intervalo previamente definido de tempo o Circuit Breaker passará do status Closed para Aberto (Open). Neste momento tentativas de execução de instruções com o objeto que representa o circuito resultarão sempre em erro;
  • Passado o período de tempo já mencionado, o Circuit Breaker entra então no status de Half-Open (Semiaberto), em que uma tentativa de execução será feita a fim de determinar se o circuito retorna para o status Closed (o esperado para situações normais).

O diagrama a seguir sumariza estas mudanças de estado:

E como o uso de Polly em .NET se encaixa em tudo isso?

Uma das opções disponibilizadas por Polly para a implementação do pattern Circuit Breaker é o tipo AsyncCircuitBreakerPolicy (namespace Polly.CircuitBreaker).

O exemplo que utilizei na live mencionada anteriormente já foi disponibilizado no GitHub (recomendo fortemente que você assista ao trecho que detalha a implementação do padrão Circuit Breaker):

https://github.com/renatogroffe/DotNet5-Worker-Polly-CircuitBreaker_ConsumoAPIContagem

Este repositório é formado por uma API REST (APIContagem), além de um Worker Service (WorkerConsumoAPIContagem) que consome esta API e no qual se definiu um Circuit Breaker com Polly.

Em WorkerConsumoAPIContagem foi implementada a classe estática CircuitBreaker:

  • Com CreatePolicy teremos a criação de uma nova Policy baseada no tipo AsyncCircuitBreakerPolicy, sendo indicados no método CircuitBreakerAsync o número máximo de exceções antes que o circuito se feche (5 ao todo), o tempo em que o mesmo permanecerá em aberto (10 segundos) e o código para cada um dos estados possíveis (parâmetros onBreak, onReset e onHalfOpen);
  • O método ShowCircuitState exibirá informações sobre cada passagem de estado.

O objeto que representa o Circuit Breaker (e gerado através de uma chamada a CreatePolicy em CircuitBreaker) será resolvido via injeção de dependências. A instância em questão foi configurada na classe Program, através do uso do método AddSingleton:

Na classe Worker teremos finalmente a utilização do Circuit Breaker:

  • A dependência para este tipo será resolvida no construtor de Worker (linhas 22 e 26);
  • A instrução a ser executado de forma protegida pelo Circuit Breaker está nas linhas 40 e 41.

Na imagem a seguir é possível observar a execução do projeto de testes. Embora falhas tenham ocorrido, o Circuit Breaker não chega a ser aberto (o status Closed permanece) e a aplicação consegue se recuperar dos problemas nesta simulação:

Após sucessivas falhas teremos a abertura do circuito (status Open), com tentativas de execução gerando exceções que indicam tal status:

Por fim, temos um exemplo de novo fechamento do circuito após o problema com a API de testes ser corrigido e a comunicação entre as aplicações restabelecida (com a passagem dos status de Open para Half Open e depois para Closed):

--

--

Renato Groffe
Renato Groffe

Written by Renato Groffe

Microsoft Most Valuable Professional (MVP), Multi-Plataform Technical Audience Contributor (MTAC), Software Engineer, Technical Writer and Speaker

No responses yet