Desenvolvimento

30 mai, 2018

Implementando o Circuit Breaker Pattern – Parte 01

Publicidade

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!