Arquitetura de Software • Nathan Geeksman • 08/04/2026

Circuit Breaker em Microserviços: Resiliência na Prática

Circuit Breaker em Microserviços: Resiliência na Prática

O desenvolvimento de software é cada vez mais complexo, pois envolve a integração de múltiplas partes e sistemas em ambientes distribuídos. Essa complexidade pode levar a problemas de desempenho e disponibilidade, como falhas cascadas e sobrecarga de serviços. Um dos conceitos utilizados para mitigar esses problemas é o circuit breaker, um padrão de projeto que ajuda a prevenir danos causados por falhas em microserviços.

O desenvolvimento de software distribuído traz consigo um problema quase inevitável: quanto mais serviços interdependentes você tem, maior a superfície de falha. Um único serviço instável pode desencadear uma reação em cadeia — o que a literatura chama de cascading failure — derrubando partes do sistema que, em teoria, não teriam nada a ver com o problema original. O Circuit Breaker é um padrão de projeto criado exatamente para quebrar esse ciclo.

A analogia com a elétrica é precisa: assim como um disjuntor corta a corrente antes que um curto-circuito queime toda a instalação, o Circuit Breaker de software interrompe chamadas a um serviço que está falhando, evitando que o problema se alastre. A ideia foi popularizada por Martin Fowler em 2014 e ganhou tração especialmente com a adoção em larga escala de microsserviços.

Os três estados do circuito

O comportamento do padrão gira em torno de uma máquina de estados simples, com três posições:

Fechado (Closed) é o estado normal. As requisições passam livremente ao serviço de destino. O circuito monitora a taxa de erros em uma janela de tempo configurável — se ela ficar abaixo do limiar definido, nada muda.

Aberto (Open) é ativado quando a taxa de falhas ultrapassa o limiar. A partir daqui, nenhuma chamada chega ao serviço problemático: o circuito retorna imediatamente um erro (ou executa um fallback), poupando recursos e evitando que um serviço lento ou indisponível segure threads em espera. Após um período de espera configurado, o circuito passa automaticamente para o terceiro estado.

Meio-aberto (Half-Open) é a fase de sondagem. O circuito deixa passar um número limitado de requisições de teste para verificar se o serviço se recuperou. Se essas chamadas tiverem sucesso, o circuito fecha novamente; se falharem, abre outra vez e o ciclo recomeça.

Essa transição automática é o que diferencia o Circuit Breaker de um simples retry com backoff: ele aprende com o comportamento do serviço e adapta sua resposta ao longo do tempo.

Implementando com Resilience4j no Spring Boot

O Hystrix da Netflix, que por muito tempo foi a referência para Circuit Breaker em Java, entrou em modo de manutenção em 2018. A alternativa moderna e ativamente mantida é o Resilience4j, uma biblioteca leve, sem dependências externas e com suporte nativo a programação reativa.

O exemplo abaixo mostra uma implementação típica com Spring Boot:

// Dependência no pom.xml:
// io.github.resilience4j:resilience4j-spring-boot3:2.2.0

import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class PagamentoService {

    private final RestTemplate restTemplate;

    public PagamentoService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @CircuitBreaker(name = "pagamento", fallbackMethod = "fallbackPagamento")
    public String processarPagamento(String payload) {
        // Chamada ao serviço externo de pagamento
        return restTemplate.postForObject("https://api.pagamento.com/processar", payload, String.class);
    }

    // Chamado automaticamente quando o circuito está aberto ou ocorre uma exceção
    public String fallbackPagamento(String payload, Exception ex) {
        return "Serviço de pagamento temporariamente indisponível. Tente novamente em instantes.";
    }
}

A configuração do circuito fica no application.yml:

resilience4j:
  circuitbreaker:
    instances:
      pagamento:
        # Janela deslizante baseada em contagem de requisições
        slidingWindowType: COUNT_BASED
        slidingWindowSize: 10

        # Abre o circuito se mais de 50% das chamadas falharem
        failureRateThreshold: 50

        # Tempo em estado aberto antes de tentar half-open (em ms)
        waitDurationInOpenState: 10000

        # Número de chamadas permitidas no estado half-open
        permittedNumberOfCallsInHalfOpenState: 3

        # Mínimo de chamadas antes de avaliar a taxa de falhas
        minimumNumberOfCalls: 5

Com essa configuração, o circuito precisa de no mínimo 5 chamadas para começar a avaliar. Se mais de 50% delas falharem em uma janela de 10 requisições, o circuito abre por 10 segundos, depois testa com 3 chamadas antes de decidir se fecha ou reabre.

O que configurar com cuidado

Os parâmetros padrão raramente são os ideais para produção. Alguns pontos que merecem atenção:

Tamanho da janela deslizante. Uma janela muito pequena torna o circuito nervoso — ele abre com poucos dados. Uma janela grande demora a reagir a degradações reais. O tipo TIME_BASED (janela de tempo) costuma ser mais estável que COUNT_BASED em serviços com tráfego irregular.

Tempo em estado aberto. Deve ser longo o suficiente para que o serviço de destino se recupere, mas não tão longo que prejudique a experiência do usuário desnecessariamente. Em serviços com reinicializações automáticas (Kubernetes, por exemplo), 10 a 30 segundos costumam funcionar bem.

Quais exceções contar como falha. Por padrão, o Resilience4j conta qualquer exceção não tratada. Mas erros de negócio — uma validação que falhou, um registro não encontrado — provavelmente não devem contar como falha do circuito. Use ignoreExceptions para excluí-los:

resilience4j:
  circuitbreaker:
    instances:
      pagamento:
        ignoreExceptions:
          - com.exemplo.excecoes.ValidacaoException
          - com.exemplo.excecoes.RecursoNaoEncontradoException

Monitoramento é parte do padrão

Um Circuit Breaker sem observabilidade é incompleto. Saber que o circuito abriu é tão importante quanto ele ter aberto.

O Resilience4j expõe métricas via Micrometer, o que permite integração direta com Prometheus e dashboards no Grafana. As métricas mais relevantes são resilience4j_circuitbreaker_state (estado atual), resilience4j_circuitbreaker_calls_total (total de chamadas por resultado) e resilience4j_circuitbreaker_failure_rate (taxa de falha em tempo real).

Além das métricas, log estruturado nos eventos de transição de estado (fechado → aberto, aberto → meio-aberto) é essencial para correlacionar incidentes com o comportamento do circuito.

Armadilhas comuns

Fallback que também falha. O método de fallback precisa ser simples e confiável — geralmente retorna um valor em cache, um dado padrão ou uma mensagem amigável. Se o fallback chamar outro serviço externo, você pode estar criando um segundo ponto de falha no momento em que o sistema já está sob estresse.

Circuito aberto mascarando o problema. O Circuit Breaker protege o sistema, mas não conserta o serviço problemático. Os alertas de monitoramento precisam continuar disparando mesmo quando o circuito está aberto, para que o time de operações saiba que há algo para investigar.

Configuração homogênea para serviços heterogêneos. Um serviço de autenticação e um serviço de recomendação têm perfis de tráfego, SLAs e tolerâncias a falha completamente diferentes. Cada circuito deve ser calibrado individualmente.

Indo além

O Circuit Breaker é frequentemente combinado com outros padrões de resiliência: Retry (novas tentativas com backoff exponencial), Rate Limiter (controle de taxa de requisições) e Bulkhead (isolamento de recursos por serviço). O Resilience4j suporta todos eles e permite combiná-los via anotações ou configuração.

Para aprofundamento, as leituras mais valiosas são o artigo original de Fowler, a documentação do Resilience4j e o livro Release It! de Michael Nygard, que discute o padrão — e muitos outros mecanismos de estabilidade — com profundidade e exemplos reais de produção.