Como usar circuit breaker com Micronaut
20 Feb 2022Introdução
Quando trabalhamos com microsserviços é comum que uma ação do usuário dispare várias requisições entre microsserviços que colaboram entre si.
Diferente de uma chamada de um serviço em um monólito que é uma simples chamada de função, em uma arquitetura de microsserviços uma chamada de um serviço geralmente é feita via HTTP, e por isso tem uma chance maior de falhar.
O que é um Circuit Breaker
Um circuit breaker é um mecanismo de proteção que desliga/abre um circuito em caso de problemas. Em português, circuit breaker significa disjuntor. Um exemplo prático é o disjuntor que todas as casas têm, em caso de sobrecarga na rede elétrica ele desliga o fornecimento de energia para evitar danos nos eletrodomésticos. Quando um disjuntor está desligado significa que o circuito está aberto, ou seja, não há fornecimento de energia.
Um circuit breaker em uma aplicação funciona de forma parecida. Você define um número máximo de falhas e caso ele seja atingido a comunicação com o serviço será desligada por algum momento, o circuito que estava fechado (deixando requisições serem feitas) ficará aberto (não aceitará requisições) por um tempo.
Passado esse tempo, o circuit breaker irá para o estado meio aberto, nesse estado ele permite que uma requisição seja feita e, em caso de sucesso o circuito é fechado novamente. Caso o problema persista o circuito ficará aberto por mais um tempo até que volte para o estado meio aberto para que seja feita uma nova verificação.
Circuit Breaker e Micronaut
O Micronaut oferece uma anotação chamada @CircuitBreaker
que pode ser usada em um cliente HTTP. Basta configurar algumas propriedades que ele já estará funcionando. Veja um exemplo abaixo:
@Client("http://localhost:8888")
@CircuitBreaker(delay = "5s", attempts = "3", reset = "30s")
interface HelloClient {
@Get("/hello")
suspend fun get(): String
}
O exemplo acima foi configurado para que o circuit breaker abra o circuito depois de 3 erros. Cada retentativa terá um intervalo de 5 segundos entre elas. Após 30 segundos o circuit breaker irá tentar novamente fazer uma requisição, caso não consiga continuará com o circuito aberto. Veja abaixo todas as propriedades que podem ser configuradas:
Propriedade | Descrição | Valor Padrão |
---|---|---|
delay | O tempo de espera entre retentativa | 500ms |
attempts | O número máximo de retentativas | 3 |
reset | Tempo de espera para trocar o estado do circuit breaker para meio aberto permitindo uma única retentativa | 20s |
multiplier | Multiplicador para calcular o tempo entre retentativas | 1 |
maxDelay | Tempo máximo de espera para uma operação completar até que o estado do circuit breaker é alterado para aberto | 5s |
includes | Tipos de exceção que serão incluídas | ALL |
excludes | Tipos de exceção que serão ignoradas pelo circuit breaker | NONE |
predicate | Pode ser usado no lugar de includes ou excludes | NONE |
Como ligar o modo debug do Circuit Breaker do Micronaut
Pode ser interessante ver o funcionamento do Circuit Breaker durante um debug. Para fazer isso, acesse o arquivo logback.xml
no diretório src/main/resources
e adicione o conteúdo abaixo dentro da tag configuration
:
<logger name="io.micronaut.retry" level="debug" />
Conclusão
Nesse artigo vimos como é simples configurar um circuit breaker para um cliente HTTP do Micronaut. Uma das vantagens de usar essa abordagem é evitar que um serviço lento cause uma queda em cascata de vários serviços do seu cluster.
Caso tenha dúvidas ou sugestões, utilize a caixa de comentários abaixo ou entre em contato pelo twitter em @john_owl