

Junior Alves
Senior Developer
Foto: Unsplash
9 de junho de 2025 • 6 minutos de leitura
Circuit Breaker: O Padrão de Design que Você Precisa Conhecer
O Guia Completo para Proteger Seus Sistemas Contra Falhas em Cascata (com Node.js)
Introdução
Imagine que é Black Friday. Um usuário clica em "Finalizar compra" no seu e-commerce. A página carrega, carrega... e da erro. O que aconteceu? O serviço de pagamentos, um microserviço externo, ficou lento e parou de responder.
Como o seu serviço de Checkout vai responder à essa situação?
Vai ficar dando retry eternamente, consumindo recursos (memória, conexões do banco, ...)?!
E se quando o Checkout parar de responder, o serviço de Carrinho e Estoque vão parar também?
Bom, é nesse cenário de caos e problemas/falhas em cascata, que brilha um conceito simples, porém muito poderoso.
Ahhh, e o mais interessante, você já até sabe a teoria por trás dele.
O Disjuntor
Sabe o disjuntor da sua casa (espero que você tenha um 🙏)? Então, o que acontece se você ligar muitos aparelhos ao mesmo tempo em uma única tomada? Sobrecarga, certo? Nesse cenário, o disjuntor é disparado para proteger a fiação da sua casa de superaquecer e causar um incêndio. Ele basicamente interrompe o fluxo de eletricidade para o circuito problemático. Os aparelhos param de funcionar, mas o resto da sua casa continua com energia, pois o problema foi contido. E por fim, para a energia voltar, você precisa ir até a caixa de luz e manualmente rearmar o disjuntor, isso claro, antes você antes deve desligar alguns aparelhos (resolver a causa da sobrecarga).
O Circuit Breaker
Ele é basicamente o disjuntor, mas no ambiente de software. Ahhh, ele faz isso de forma automática. Pense no Circuit Breaker como um Wrapper que você coloca em volta de chamadas a um serviço externo que pode falhar.
Como o Circuit Breaker funciona?
O Circuit Breaker tem basicamente 3 estados:
- 🟢
CLOSED
(Fechado)
- Esse é o estado default. A "eletricidade está fluindo".
- O Circuit Breaker fica monitorando as chamadas. Se uma falha acontecer (timeout, erro 500, ...), ele anota.
- 🔴
OPEN
(Aberto)
- Esse é o estado "disparado".
- Quando acontece? Ele dispara e muda de
CLOSED
paraOPEN
quando o número de falhas atinge um limite que você configurou. Vamos ver na prática daqui a pouco. - Enquanto está
OPEN
, ele não tenta mais fazer a chamada de rede para o serviço. Ele já falha imediatamente, retornando um erro.
- 🟡
HALF-OPEN
(Meio-Aberto)
-
Após um tempo configurado no estado
OPEN
, o Circuit Breaker não volta direto para oCLOSED
. Ele volta com cautela, emHALF-OPEN
-
Ele age como um "teste". Ele permite que uma única requisição passe para o serviço que está com falha.
-
Se essa request retornar sucesso, ele assume que o sistema voltou, alterando seu estado para
CLOSED
e o fluxo de requests normaliza. -
Se essa request de teste falha, ele volta imediatamente para o estado
OPEN
, e inicia um novo período de espera.
Mão na massa: Implementando Circuit Breaker em Node.js
Chega de teoria, vamos para o código! E ao invés de reinventar a roda, vamos usar uma lib para nos ajudar, a Opossum.
Passo 1: Preparando o ambiente
mkdir circuit-breaker-example
cd circuit-breaker-example
npm init -y
npm install express opossum
Passo 2: Criando o vilão (nosso serviço instável)
// unstableService.js
function pay() {
return new Promise((resolve, reject) => {
// Simula uma falha em 50% das vezes
const shouldFail = Math.random() > 0.5;
setTimeout(() => {
if (shouldFail) {
console.log('❌ Pagamento Falhou!');
reject(new Error('Serviço de pagamento indisponível.'));
} else {
console.log('✅ Pagamento Realizado com Sucesso!');
resolve({ status: 'Aprovado' });
}
}, 1000); // Simula latência de rede
});
}
module.exports = { pay };
Passo 3: Criando o Circuit Breaker
- Crie o arquivo principal index.js.
// index.js
const express = require('express');
const Opossum = require('opossum');
const { pay } = require('./unstableService');
const app = express();
const PORT = 3000;
// 1. Configuração do Circuit Breaker
const options = {
timeout: 3000, // Se a função demorar mais que 3s, falha
errorThresholdPercentage: 50, // Dispara se 50% das requests falharem
resetTimeout: 30000 // Tenta se recuperar após 30s
};
const breaker = new Opossum(pay, options);
// 2. Definindo o "Fallback"
// O que fazer quando o circuito está aberto?
breaker.fallback(() => ({
status: 'Fallback',
message: 'Serviço de pagamento indisponível no momento. Tente novamente mais tarde.'
}));
// 3. Monitorando os eventos do Breaker (ótimo para logs!)
breaker.on('open', () => console.log(`CIRCUITO ABERTO: O breaker disparou.`));
breaker.on('halfOpen', () => console.log(`CIRCUITO MEIO-ABERTO: Testando a recuperação...`));
breaker.on('close', () => console.log(`CIRCUITO FECHADO: O serviço se recuperou.`));
breaker.on('fallback', (result) => console.log(`FALLBACK: Executado com o resultado: ${result.message}`));
// 4. Nossa rota de Checkout que usa o Breaker
app.get('/checkout', async (req, res) => {
console.log('\n--- Nova Tentativa de Checkout ---');
try {
const result = await breaker.fire();
console.log('Resultado da operação:', result);
res.json(result);
} catch (err) {
console.error('Erro na chamada:', err.message);
res.status(500).json({ error: err.message });
}
});
app.listen(PORT, () => {
console.log(`Servidor rodando na porta ${PORT}.`);
console.log('Acesse http://localhost:3000/checkout para testar.');
});
Passo 4: Testando e Observando
Instrua o leitor a rodar node index.js e acessar http://localhost:3000/checkout várias vezes (usando o navegador ou uma ferramenta como o curl).
- Peça para ele observar o console:
- No início, as chamadas vão variar entre sucesso e falha.
- Após algumas falhas, ele verá a mensagem "CIRCUITO ABERTO".
- A partir daí, todas as chamadas serão instantaneamente rejeitadas e a mensagem de fallback será exibida.
- Após 30 segundos, ele verá "CIRCUITO MEIO-ABERTO".
- Se a próxima chamada funcionar, o circuito fechará. Se falhar, ele abrirá novamente.
Pratique para fixar 🎉
Conclusão
Chegamos ao fim da nossa jornada e agora você tem um novo superpoder: a resiliência. O Circuit Breaker é como aquele herói que atua nos bastidores para garantir que o show continue, mesmo quando um dos atores principais falha.
Lembre-se dos ganhos que ele traz para o seu projeto:
- Adeus, efeito dominó: Ele é o guarda que impede que uma pequena falha cause uma catástrofe em todo o seu ecossistema de microserviços.
- Usuários mais felizes: Ninguém gosta de esperar. O fail-fast (falha rápida) do Circuit Breaker oferece uma experiência muito mais agradável do que o suspense de uma requisição que nunca termina.
- Sistemas que se curam: Você cria um ambiente inteligente onde os componentes têm a chance de se recuperar sozinhos, sem que você precise intervir manualmente no meio da madrugada.
Muito obrigado por ler até aqui, espero ter ajudado a entender sobre o Circuit Breaker. Qualquer dúvida ou sugestão é sempre bem vinda nos comentários!
Até o próximo post 🚀
Curtiu? Compartilhe esse post: