Circuit Breaker - Saiba tudo sobre esse pattern essencial
Aprenda a implementar o padrão Circuit Breaker com Resilience4j no Spring Boot. Entenda os estados CLOSED, OPEN e HALF_OPEN para criar sistemas resilientes.
Neste artigo, apresento um dos padrões mais importantes na arquitetura de microserviços: o Circuit Breaker. Mais do que evitar falhas, esse padrão é fundamental para construir aplicações resilientes, capazes de lidar com indisponibilidades externas sem comprometer toda a cadeia de serviços. Saber aplicar corretamente mecanismos de tolerância a falhas é um dos pontos que diferenciam quem apenas “faz funcionar” de um desenvolvedor sênior, que projeta sistemas preparados para operar em cenários reais de produção.
Ao desenvolver sistemas modernos, é praticamente inevitável a necessidade de integrar e consumir informações de outros serviços, sejam eles internos ou de terceiros. No entanto, quando uma dessas dependências é crítica para o funcionamento da aplicação, surge a pergunta: se esse serviço falhar, toda a aplicação deve ser interrompida?
A resposta é não. Sistemas bem projetados precisam ser capazes de lidar com falhas externas de forma controlada, mantendo o funcionamento mesmo em cenários adversos. É justamente sobre esse tema — tolerância a falhas e resiliência — que falaremos no conteúdo de hoje.
1. Pré-requisitos para esse artigo
Para acompanhar este artigo e compreender plenamente os exemplos apresentados, é importante atender aos seguintes pré-requisitos:
- As implementações e exemplos serão realizados utilizando Spring Boot (Java);
- É recomendado possuir conhecimento intermediário em Java;
- A aplicação deve realizar integrações com outros serviços, apresentando latências variáveis ou potencialmente mais elevadas — cenário comum em arquiteturas de microserviços.
Ao longo do artigo, assumo que você já possui um projeto Spring Boot inicializado e familiaridade com os conceitos da linguagem Java.
2. Breve resumo
Em residências, utilizamos disjuntores no quadro de energia para interromper automaticamente a passagem de corrente elétrica quando ela ultrapassa os limites seguros, protegendo tanto a estrutura quanto os equipamentos contra danos ou incêndios.
Nos sistemas distribuídos, o Circuit Breaker exerce exatamente esse mesmo papel. Ele monitora continuamente as chamadas para um serviço dependente e, ao identificar falhas recorrentes ou comportamentos anormais, interrompe temporariamente novas tentativas de acesso, protegendo a aplicação contra falhas em cascata.
Esse mecanismo opera por meio de três estados bem definidos: CLOSED (fechado), OPEN (aberto) e HALF_OPEN (semi-aberto), permitindo que o sistema degrade de forma controlada e se recupere automaticamente quando o serviço dependente volta a se comportar de maneira saudável.
3. Mas o que significa cada status?
3.1 CLOSED (Fechado)
Neste estado, a aplicação envia requisições normalmente para o microserviço dependente. O Circuit Breaker permanece apenas observando e coletando métricas, como taxa de falhas e latência das chamadas. Com base nas configurações definidas (que veremos mais adiante), ele decide se o comportamento do serviço ainda é saudável ou se deve transitar para o próximo estado.
3.2 OPEN (Aberto)
Quando o Circuit Breaker entra no estado OPEN, todas as requisições destinadas ao serviço dependente são bloqueadas imediatamente, sem que a chamada seja sequer realizada. O objetivo é evitar sobrecarga e falhas em cascata. Nesse momento, entra em ação o fallback, responsável por fornecer uma resposta alternativa e manter o sistema funcional. Após um período previamente configurado, o Circuit Breaker permite a execução de algumas chamadas de teste para verificar se o serviço já se recuperou. Caso positivo, ocorre a transição para o estado HALF_OPEN.
3.3 HALF_OPEN (Semi-aberto)
No estado HALF_OPEN, o Circuit Breaker libera um número limitado de requisições ao serviço dependente. Essas chamadas funcionam como uma validação controlada da saúde do serviço. Se a maioria das requisições for bem-sucedida — de acordo com os critérios configurados — o circuito retorna ao estado CLOSED, retomando o fluxo normal. Caso as falhas persistam, o Circuit Breaker volta para o estado OPEN, reiniciando o ciclo de proteção.
Como podemos observar, a analogia com o disjuntor elétrico facilita a compreensão do comportamento desse padrão: ele interrompe o fluxo quando detecta risco, testa a recuperação de forma gradual e só restabelece totalmente quando o ambiente volta a operar de maneira segura.

Perceba: No eixo X o circuito permanece fechado até cerca de 8, fica meio-aberto entre 17 e 24 e com o sucesso, volta a permanecer fechado.
4. Quando e por que eu deveria usar?
Imagine um sistema de monitoramento de câmeras no qual existe um serviço central responsável por orquestrar chamadas para outros microserviços. Em um primeiro momento, esse serviço consome um JSON com os metadados de uma câmera e, em seguida, realiza uma nova chamada para um serviço de imagens a fim de obter a imagem associada àquele registro.

A pergunta fundamental nesse cenário é: o que acontece se o serviço de imagens ficar indisponível ou responder de forma lenta? Sem nenhum mecanismo de proteção, o sistema central continuará tentando realizar chamadas, aumentando a latência, consumindo recursos desnecessários e, potencialmente, causando uma cascata de falhas que pode comprometer toda a aplicação.
É exatamente nesse ponto que o Circuit Breaker entra em ação. Ao detectar falhas recorrentes ou degradação do serviço de imagens, ele interrompe temporariamente novas requisições, evitando a sobrecarga do serviço problemático e permitindo que ele tenha tempo para se recuperar. Além disso, o uso de fallbacks possibilita definir respostas alternativas — como uma imagem padrão ou um estado degradado — garantindo que o sistema continue operando de forma controlada e resiliente.
Sempre que sua aplicação depender do consumo de informações provenientes de outros microserviços — especialmente em cenários onde cada dependência pode apresentar instabilidade — a implementação do Circuit Breaker deixa de ser opcional e passa a ser um requisito fundamental de arquitetura para garantir resiliência, estabilidade e previsibilidade em produção.
5. Antes do código, vamos analisar dados de observabilidade

A linha na horizontal é a failureRateThreshold. Enquanto a taxa de erro estiver abaixo dela, o circuito permanece CLOSED (FECHADO). As configurações Sliding Window falaremos mais adiante. Não se preocupe.

A diferença entre a aplicação sem circuit breaker (azul) para a que está com ele ativo (laranja) é gritante. Perceba que existe um padrão “fast-fail”. Ou seja, a aplicação nem tentou requisitar o microserviço com problema. Imediatamente retornou o erro, mantendo-a estável.

Quando o circuito abre, é natural que o Throughput caia. Como as requisições são bloqueadas, temos preservação de recursos como CPU, Threads, conexões, etc.).
6. Vamos a implementação
No Spring Boot o pattern do circuit breaker é implementado a partir da biblioteca Resilience4j.
Adicione a biblioteca ao pom.xml
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot3</artifactId>
<version>2.3.0</version>
<scope>compile</scope>
</dependency>
Adicione essas configurações ao application.properties
resilience4j.circuitbreaker.configs.default.sliding-window-type=COUNT_BASED
resilience4j.circuitbreaker.configs.default.sliding-window-size=100
resilience4j.circuitbreaker.configs.default.minimum-number-of-calls=10
resilience4j.circuitbreaker.configs.default.failure-rate-threshold=50
resilience4j.circuitbreaker.configs.default.slow-call-rate-threshold=100
resilience4j.circuitbreaker.configs.default.slow-call-duration-threshold=60000
resilience4j.circuitbreaker.configs.default.wait-duration-in-open-state=60000
resilience4j.circuitbreaker.configs.default.permitted-number-of-calls-in-half-open-state=10
resilience4j.circuitbreaker.configs.default.automatic-transition-from-open-to-half-open-enabled=true
resilience4j.circuitbreaker.configs.default.register-health-indicator=true
Explicação:
Com essa configuração, o Circuit Breaker do Resilience4j passa a operar com uma janela deslizante baseada em quantidade de chamadas, analisando sempre as últimas 100 requisições realizadas. No entanto, ele só começa a tomar decisões após atingir no mínimo 10 chamadas, evitando que o circuito seja aberto com base em um volume de dados estatisticamente irrelevante. A partir desse ponto, se 50% ou mais das chamadas dentro da janela falharem, o Circuit Breaker entra em estado OPEN, interrompendo novas tentativas de comunicação com o serviço dependente.
Além da taxa de falhas, a configuração também considera chamadas lentas. Neste caso, uma chamada só é classificada como lenta se ultrapassar 60 segundos, e o limite de tolerância para chamadas lentas está definido como 100%, o que na prática desativa esse critério como fator de abertura do circuito. Ou seja, o Circuit Breaker será acionado prioritariamente por falhas, e não por latência.
Quando o circuito entra em estado OPEN, ele permanece bloqueando novas requisições por 60 segundos. Após esse período, ocorre automaticamente a transição para o estado HALF_OPEN, no qual são permitidas até 10 chamadas de teste. O resultado dessas chamadas define se o serviço está recuperado: caso tenham sucesso, o circuito retorna ao estado CLOSED; caso contrário, ele volta para OPEN, reiniciando o ciclo de proteção.
Por fim, o estado do Circuit Breaker é exposto através do Spring Boot Actuator, permitindo que ferramentas de monitoramento e observabilidade consultem sua saúde em tempo real. Isso facilita a identificação de falhas, a análise de comportamento em produção e a tomada de decisões operacionais baseadas no estado atual do circuito.
Implementação na service:
@CircuitBreaker(
name = "imageService",
fallbackMethod = "getImageFallback"
)
public byte[] getImage(String imageId) {
// Tenta retornar a imagem do microserviço
return imageClient.getImage(imageId);
}
/**
* Fallback executado quando:
* - serviço de imagem está indisponível
* - timeout ocorre
* - circuito está OPEN
*/
public byte[] getImageFallback(String imageId, Throwable ex) {
// Log técnico para observabilidade
log.warn("Fallback acionado para imageId={}, motivo={}", imageId, ex.getMessage());
// Exemplo simples: retorna imagem placeholder para manter aplicação resiliente
return loadPlaceholderImage();
}
7. Conclusão
Ao longo deste artigo, você viu como implementar um dos padrões mais relevantes — e mais utilizados — na arquitetura de microserviços: o Circuit Breaker. Mais do que uma biblioteca ou uma configuração, ele representa uma estratégia de resiliência, essencial para sistemas que operam em ambientes distribuídos e sujeitos a falhas.
Não existe bala de prata para eliminar todos os problemas de sistemas distribuídos. No entanto, existem soluções bem estabelecidas que, quando aplicadas no contexto correto, elevam significativamente a robustez da aplicação. O Circuit Breaker é uma dessas soluções: simples no conceito, poderoso na prática e indispensável em cenários reais de produção.