Fala, galera!
Estou criando uma série de artigos para explicar o conceito de Circuit Breaker. Este padrão está se tornando muito comum em cenários de micro serviços, onde temos chamadas a serviços ou recursos externos que podem entrar em estado de falha. Saber como tratar as exceções e criar serviços resilientes à falha nos dias de hoje se torna cada mais vez necessário, e nesta série de artigos vou abordar como podemos usar o Pattern Circuit Breaker.
Neste primeiro artigo mostrarei os principais conceitos desse pattern, na segunda parte estaremos implementando o nosso Circuit Breaker, e por último estarei mostrando componentes que implementam o Circuit Breaker Pattern
Em um ambiente distribuído, temos diversas chamadas a recursos externos e – claro – estes recursos externos podem entrar em estado de falha. Essas falhas podem ser, por exemplo, uma rede lenta, timeouts, ou uma implementação errada, causando status code 500.
Essas falhas – na maiorias das vezes – são corrigidas em um espaço curto de tempo, e uma aplicação robusta deve saber lidar com essas situações, criando uma estratégia de repetição caso um serviço entre em estado de falha.
O Circuit Break Pattern tem uma proposta diferente de um Retry Pattern. O Retry Pattern habilita uma aplicação a fazer diversas tentativas, nas quais – em um determinado momento – a chamada será bem-sucedida.
O Circuit Break Pattern previne aplicações de fazer chamadas a operações que estão em estado de falha. Uma aplicação pode combinar os dois Pattern usando o Retry Pattern e o Circuit Break Pattern e essa junção é a mais comum de ser feita.
O Circuit Breaker Pattern
O Circuit Breaker atua como um proxy em operações que podem falhar. Esse proxy monitora o número de falhas ocorridas em uma chamada e decide se permite que a operação continue ou retorne uma exceção imediatamente.
O proxy na realidade é uma maquina de estado com três estágios que imitam um disjuntor elétrico de uma casa, que no caso de falha, o disjuntor abre o circuito não causando danos a equipamento eletrônicos, cortando a passagem de eletricidade; e quando está tudo ok, ele fecha o circuito e deixa a corrente elétrica passar.
- Fechado: Uma chamada para um serviço é feita, o proxy mantém a contagem do número de falhas recentes e caso a chamada não for bem-sucedida, o proxy aumentará a contagem de falhas. Caso a contagem exceda o limite em um determinado período de tempo, o proxy entrará em Circuito Aberto.
- Aberto: A chamada para um serviço falha imediatamente e uma exceção é retornada
- Entreaberto: O estado de entreaberto é quando um número limitado de chamadas a um serviço for feito, e caso forem bem-sucedidas, o proxy irá considerar que o problema foi corrigido e mudará o estado para Fechado. Se alguma operação falhar, o proxy irá considerar que ainda estamos com falha e voltará o estado para Aberto.
O estado Entreaberto é útil para impedir que um serviço que acabou de entrar no ar seja bombardeado com solicitações de forma repentina.
Considerações
Alguns pontos que devemos considerar quando vamos utilizar o Circuit Breaker Pattern:
- Tratamento de exceção: Sua aplicação deve estar preparada para tratar as exceções geradas pelo Circuit Breaker.
- Registro em log: O Circuit Breaker deve logar toda a atividade gerenciada por ele, tanto as solicitações com falha, quanto as bem-sucedidas.
- Capacidade de Recuperação: O Circuit Breaker deve ter capacidade de recuperação. Ele deve ser inteligente o suficiente para saber quando mudar de estado, por exemplo, se o circuito estiver aberto por muito tempo, ele pode estar gerando exceções erradas, pois é possível que o serviço com problema já esteja em funcionamento normal .
- Simultaneidade: O Circuit Breaker pode e deve ser acessado por diversas instâncias simultâneas. A implementação do Circuit Breaker não deve bloquear chamadas a serviços e nem criar overhead em chamadas.
- Reprodução de falhas : O Circuit Breaker no seu estado aberto em vez de simplesmente soltar uma exceção, ele deverá também registrar todo o detalhe da solicitação e a exceção da causadora do evento.
Quando usar esse padrão
- Quando temos um serviço que tem que fazer chamadas a serviços externos.
Quando não usar esse padrão
- Para tratar de recursos locais como acesso à base de dados locais, estrutura em memória, caches e afins.
- Para substituir o tratamento de exceções lógicas do seu serviço.
E assim chegamos ao fim do primeiro artigo da série sobre Circuit Breaker. No próximo, estaremos implementando nosso Circuit Breaker e entendendo mais ainda o seu funcionamento
Abraços e até o próximo artigo!