# Microsserviços: Padrão Circuit Breaker para melhorar a resiliência

A arquitetura de microsserviços distribui aplicações em vários serviços, introduzindo desafios em suas interações. Falhas — sejam devido a problemas de rede, falhas em contêineres ou sobrecarga de serviços — são inevitáveis e podem interromper cadeias inteiras de operações. O **padrão Circuit Breaker** aborda esses desafios isolando serviços com falhas para evitar erros em cascata, garantindo que outros serviços permaneçam operacionais.

<figure><img src="https://content.gitbook.com/content/XfrDexGOLMin51pAiWkq/blobs/DubEr6s5Fs7VzcgqahiE/PT1.png" alt=""><figcaption><p><em>Implementação do circuit breaker para cada serviço externo em um sistema distribuído.</em></p></figcaption></figure>

Este caso de uso demonstra como a implementação desse padrão pode aumentar a resiliência e minimizar interrupções em suas integrações. Ao final deste artigo, você aprenderá como a **Digibee** pode ajudá-lo a implementar o padrão Circuit Breaker, garantindo que seus sistemas permaneçam resilientes diante de falhas.

## Por que os Circuit Breakers são importantes

Um **Circuit Breaker** é um padrão de design que ajuda a gerenciar falhas de forma elegante.

Assim como um disjuntor elétrico evita danos interrompendo o fluxo de energia quando ocorre uma sobrecarga, um **circuit breaker de software** interrompe temporariamente as solicitações a um serviço quando detecta falhas repetidas.

Para as empresas, essa abordagem é inestimável. Ao prevenir falhas em cascata, o Circuit Breaker dá aos sistemas o tempo necessário para se recuperarem sem sobrecarregar os recursos. Isso resulta em uma experiência do usuário mais estável e reduz o risco de perda de receita devido a períodos de inatividade.

## Como funciona

Um Circuit Breaker monitora as **taxas de sucesso e falha das solicitações** a um serviço e alterna entre três estados:

* **Circuito fechado (closed):** Todas as solicitações passam, assumindo que o serviço está saudável.
* **Circuito aberto (open):** As solicitações são bloqueadas após as falhas excederem um limite[^1]\* predefinido, evitando mais pressão sobre o serviço com falha.
* **Circuito semiaberto (half-open):** Um número limitado de solicitações de teste é permitido para verificar se o serviço se recuperou.

<figure><img src="https://content.gitbook.com/content/XfrDexGOLMin51pAiWkq/blobs/4lrGSZ0MfmG2hUm53VTE/pt2.png" alt=""><figcaption></figcaption></figure>

Ao usar um Circuit Breaker, você pode:

* **Evitar a sobrecarga** de serviços com falha, interrompendo solicitações desnecessárias.
* Fornecer **respostas de** [**fallback**](#user-content-fn-2)[^2]\* para minimizar o impacto no usuário.
* Dar ao serviço com falha um **tempo para se recuperar** antes de tentar reconectar.

## Casos de Uso

Abaixo estão cenários onde os circuit breakers melhoram significativamente a confiabilidade do sistema:

### Cenário 1: Sistema de reserva de voos

Em um sistema de reserva de voos, o **Serviço de Reserva** depende do **Serviço de Informações de Voos** para obter dados de voos disponíveis. Se o Serviço de Informações de Voos ficar inativo ou tiver tempos de resposta lentos, o Serviço de Reserva pode se tornar não-responsivo.

#### **Processo de backend**

1. O **Serviço de Reserva** envia solicitações ao **Serviço de Informações de Voos**.
2. Se o serviço falhar repetidamente, o Circuit Breaker abre, impedindo novas solicitações ao serviço com falha.
3. O **Serviço de Reserva** retorna uma resposta de fallback ou informa ao usuário que o serviço está indisponível.

### Cenário 2: Processamento de pedidos de e-commerce

Uma plataforma de e-commerce depende de vários microsserviços. Se o **Serviço de Pagamento** estiver com problemas, o **Serviço de Pedidos** pode usar um circuit breaker para evitar que novas solicitações de pagamento sejam enviadas até que o serviço se recupere.

#### **Processo de backend**

1. O **Serviço de Pedidos** envia solicitações de pagamento ao **Serviço de Pagamento**.
2. Se o **Serviço de Pagamento** encontrar falhas, o Circuit Breaker abre, e o **Serviço de Pedidos** responde com uma mensagem de erro temporária ou usa um método de *fallback* para concluir o pedido.

## Colocando a teoria em prática

Imagine um pipeline projetado para se integrar a serviços externos, como uma **API de Serviço de Endereços**, para validar endereços com base no código postal inserido durante o registro do usuário. O pipeline deve atender aos seguintes requisitos:

* **Buscar detalhes completos do endereço** via serviço externo.
* **Usar um Circuit Breaker** para lidar com falhas do servidor, evitando tentativas excessivas.

Para este caso de uso, o foco será na **implementação do Circuit Breaker**, e não no pipeline em si.

<figure><img src="https://content.gitbook.com/content/XfrDexGOLMin51pAiWkq/blobs/09w7wbfUzwhxgfOJKXZx/PT3.png" alt=""><figcaption><p><em>Representação simplificada de um fluxo de circuit breaker: ilustrando como as solicitações a uma API de Serviço de Endereços são gerenciadas durante operação normal, cenários de falha e recuperação do circuit breaker.</em></p></figcaption></figure>

### Passo a passo

**1. Configuração do pipeline**

* Configure um trigger [**REST**](https://app.gitbook.com/s/SKBJ6ZiEWBU93x170HH4/triggers/web-protocols/rest) com o método **POST** para receber dados do usuário (código postal).&#x20;

**2. Armazenamento do código postal**

* Salve os dados na **memória de execução** ([**Session Management**](https://app.gitbook.com/s/SKBJ6ZiEWBU93x170HH4/connectors/structured-data/session-management)) e recupere-os antes de chamar a API de Endereços.&#x20;

**3. Verificação do status do Circuit Breaker**

* A próxima etapa consulta o **status do Circuit Breaker** em um banco de dados temporário (como um [**Object Store**](https://app.gitbook.com/s/SKBJ6ZiEWBU93x170HH4/connectors/structured-data/object-store)). Especificamente, verifica se o Circuit Breaker está **aberto** ou **fechado**.
  * **Se fechado**, o fluxo prossegue com as operações normais do pipeline.
  * **Se não fechado** (indicando que falhas recentes excederam o limite), ele bloqueia novas solicitações para evitar falhas em cascata.&#x20;

**4. Tratamento de circuito fechado (Block Execution - onProcess)**

* Se o circuito estiver fechado e uma chamada à API do Serviço de Endereços for feita, a resposta é processada e retornada ao usuário.
* Se ocorrer um erro (indisponibilidade do serviço, etc.), o pipeline é direcionado para o subfluxo **onException** para lidar com a falha.&#x20;

**5. Tratamento de circuito fechado (Block Execution - onException)**

* A **contagem de falhas** é rastreada em um [**Object Store**](https://app.gitbook.com/s/SKBJ6ZiEWBU93x170HH4/connectors/structured-data/object-store) (ou qualquer outro banco de dados temporário).
  * **Se o limite de falhas não for excedido**, a contagem de falhas é incrementada em 1.
  * **Se o limite de falhas for excedido** (por exemplo, 15 falhas), o **Circuit Breaker é acionado**, e o status é atualizado para **aberto** para evitar novas solicitações ao serviço com falha. Assim, na próxima solicitação, o fluxo será redirecionado para o caminho do circuito "aberto", onde o pipeline bloqueará novas tentativas de interação com o serviço de endereço até que o circuito seja fechado novamente.

**6. Abertura do Circuit Breaker**

* Um conector [**JSON Generator**](https://app.gitbook.com/s/SKBJ6ZiEWBU93x170HH4/connectors/tools/json-generator) calcula o tempo desde que o circuito foi aberto em relação ao timestamp atual da execução. Se exceder X minutos, o circuito é redefinido para fechado, permitindo novas solicitações.

**7. Sucesso ou Falha após tempo decorrido**

* Se o circuito estiver aberto por mais de **X minutos**, o circuito é **fechado** (redefinido) e, durante a **próxima execução do pipeline**, o Circuit Breaker tentará **reabrir** enviando uma nova solicitação ao serviço.

<figure><img src="https://content.gitbook.com/content/XfrDexGOLMin51pAiWkq/blobs/TawORNKj7EBYbjOExIK8/PT%204.png" alt=""><figcaption><p>Na captura de tela acima, você pode ver o padrão Circuit Breaker implementado no pipeline.</p></figcaption></figure>

{% hint style="info" %}
Para ver um exemplo do padrão Circuit Breaker revisado usado neste caso de uso, acesse o [desafio do Circuit Breaker no Digibee Academy](https://digibee.academy/circuit-breaker-implementation/) e procure a folha de respostas lá.
{% endhint %}

## Considerações finais

O **padrão Circuit Breaker** é uma consideração importante ao usar uma arquitetura de microsserviços. Essa abordagem ajuda as integrações a manter a **disponibilidade e a resiliência**.

Explore mais possibilidades em nosso [Portal de Documentação](https://docs.digibee.com/documentation/pt-br), participe do Desafio do Circuit Breaker ou inscreva-se no curso e webinar de Métricas e Monitoramento no [Digibee Academy](https://digibee.academy/courses/event-driven-arch-2).\
Além disso, visite nosso [Blog](https://www.digibee.com/blog/unleash-the-power-of-event-driven-integration/) para mais casos de uso e insights.

Se tiver feedback sobre este caso de uso ou sugestões para futuros artigos, adoraríamos ouvir sua opinião através do nosso [formulário de feedback](https://docs.google.com/forms/d/e/1FAIpQLSd2EnkeEI6TOfgdgJ5gv16Ukozt9oY5Rm2N8X9o5JF4w5kB3Q/viewform)

[^1]: Pro-tip: Limites são normalmente definidos com base em padrões de falhas anteriores, impacto nos negócios ou ou garantias de tempo de atividade do serviço.

[^2]: **Respostas de fallback** podem incluir mostrar uma mensagem "Serviço temporariamente indisponível", alternar para um serviço de backup, etc.
