Guia prático para implementar retries exponenciais e circuit breaker em integrações entre ERP e marketplaces

Por · Publicado em · 8 min de leitura

Diagrama estilizado em tons de azul com nós e linhas conectando pontos, representando rede distribuída.
Conceito visual de integrações e fluxos entre sistemas distribuídos. Foto: geralt / Pixabay

Este guia prático para implementar retries exponenciais e circuit breaker em integrações entre ERP e marketplaces mostra como manter resiliência sem duplicar pedidos ou violar limites de API. Você verá quando aplicar cada padrão, como configurar backoff com jitter, projetar idempotência e monitorar. Útil para equipes técnicas e responsáveis pelo negócio.

Quando usar retries e circuit breaker nas integrações ERP–marketplaces

Integrações com marketplaces sofrem com timeouts, picos de tráfego, janelas fiscais e rate limits. Retries exponenciais e circuit breaker estabilizam o fluxo, evitam quedas em cascata e reduzem retrabalho.

Sinais de que você precisa desses padrões: erros 429/5xx frequentes, duplicação de pedidos, estoque divergente, picos de latência e janelas de faturamento sensíveis ao tempo.

Em cenários de alto volume, combinar com filas ajuda a desacoplar e nivelar picos. Veja critérios em SQS vs RabbitMQ gerenciado.

  • APIs com rate limit agressivo (429) no fechamento do mês.
  • Time-outs intermitentes e DNS falhando esporadicamente.
  • POSTs que, ao reprocessar, geram pedidos duplicados.
  • Processos noturnos que congestionam integrações e relatórios.

Backoff exponencial com jitter: parâmetros e exemplo

Retries simples em intervalos fixos amplificam congestionamento. Use backoff exponencial com jitter para espaçar tentativas e evitar rajadas sincronizadas. A cada falha, o tempo de espera cresce, e um ruído aleatório (jitter) dispersa as tentativas.

Parâmetros práticos para configurar: tentativas máximas, fator de crescimento, limite superior, jitter (full ou equal) e deadline total da operação. Respeite o rate limit do marketplace e aborte com erro claro quando o deadline expirar.

Referências úteis: Exponential Backoff and Jitter (AWS) e Guidance de backoff (Google Cloud).

  • Max attempts: define teto para falhas reais.
  • Base delay e fator: por exemplo, 200 ms e fator 2.
  • Max backoff: evita esperas excessivas.
  • Jitter: "full" reduz sincronização entre clientes.
  • Deadline total: cancele se o tempo de negócio estourar.
function retryWithExponentialBackoff(op, isRetryable, maxAttempts=6,
                                      base=0.2s, factor=2, maxDelay=10s,
                                      jitter='full', deadline=30s) {
  start = now()
  attempt = 1
  while (true) {
    try {
      return op()
    } catch (err) {
      if (attempt >= maxAttempts || !isRetryable(err)) throw err
      elapsed = now() - start
      if (elapsed > deadline) throw DeadlineExceeded
      // Exponential delay
      delay = min(maxDelay, base * (factor ** (attempt - 1)))
      // Jitter
      if (jitter == 'full') delay = random(0, delay)
      if (jitter == 'equal') delay = (delay / 2) + random(0, delay / 2)
      sleep(delay)
      attempt++
    }
  }
}

Idempotência: evitando pedidos e atualizações duplicadas

Retries só são seguros com operações idempotentes. Para POSTs, gere uma chave de idempotência por pedido/entidade e persista o resultado associado. Assim, reenvios retornam o mesmo efeito sem duplicar.

Projete o ERP para registrar processamentos com chaves únicas e metadados: status final, payload normalizado, horário e TTL opcional quando cabível. Nunca reenvie POST sem idempotência.

Para fluxo assíncrono, use filas e controle de deduplicação. Entenda trade-offs de entrega eventual e chaves idempotentes em entrega eventual ERP–loja virtual.

  • Defina escopo da chave: por pedido, item, nota, ou operação.
  • Armazene hash do payload para detectar diferenças sutis.
  • Retorne 200/201 com o mesmo body quando reprocessar.
  • Faça expiração de chaves quando o domínio permitir.
  • Inclua a chave em logs e métricas para rastreio.

Circuit breaker na prática: estados, limiares e fallback

Circuit breaker evita sobrecarregar serviços instáveis. Estados: fechado (normal), aberto (bloqueia chamadas) e half‑open (testes limitados). Ele abre ao detectar taxa de falha alta em janela deslizante.

Defina limiares claros: taxa de erro, timeouts sucessivos, volume mínimo e duração de abertura. Planeje fallback específico para cada operação crítica.

Estratégias comuns: enfileirar para reprocesso, servir cache recente, ou degradar funcionalmente (ex.: pausar atualização de fotos, manter preço/estoque).

  • Janela deslizante com N chamadas mínimas para estatística.
  • Erro composto: 5xx, timeouts e 429 contam, 4xx de validação não.
  • Half‑open com poucas tentativas e espaçamento maior.
  • Backoff para reabrir após período de resfriamento.
  • Exponha estado do breaker em métricas e healthchecks.
class CircuitBreaker {
  state = 'CLOSED'
  openedAt = null
  failureCount = 0
  successCount = 0
  function call(fn, isRetryable) {
    if (this.state == 'OPEN') {
      if (now() - this.openedAt < cooldown) throw OpenCircuit
      this.state = 'HALF_OPEN'
      this.failureCount = 0; this.successCount = 0
    }
    try {
      res = retryWithExponentialBackoff(fn, isRetryable)
      if (this.state == 'HALF_OPEN') this.successCount++
      if (this.successCount >= halfOpenSuccesses) this.close()
      return res
    } catch (e) {
      this.failureCount++
      if (this.shouldOpen()) this.open()
      throw e
    }
  }
  function shouldOpen() { return this.failureRate() > threshold && this.sampleSize() >= minSamples }
  function open() { this.state = 'OPEN'; this.openedAt = now() }
  function close() { this.state = 'CLOSED'; this.failureCount = 0; this.successCount = 0 }
}

Qual erro merece retry? Tabela de decisão

Nem todo erro deve ser retentado. Classifique primeiro. Abaixo, um mapa prático para integrações ERP–marketplaces. Ajuste conforme políticas de cada API e contrato de negócio.

Categoria de erro Exemplos Retentar? Estratégia recomendada
Rate limit 429, headers Retry-After Sim Backoff exponencial com jitter respeitando Retry-After; registrar métrica de saturação
Falha transitória do provedor 5xx, timeout, DNS Sim Retries com deadline; envolver com circuit breaker
Conflito/reprocesso 409, recurso já existe Depende Verificar idempotência; recuperar estado e prosseguir
Erro de validação 400, schema inválido Não Corrigir payload; criar alerta e dead-letter
Autenticação/autorização 401/403 Não Renovar credenciais; bloquear fluxo até resolver
Negócio (regra) 422, limite tributário Não Tratamento no ERP; fila de revisão manual
Incerteza de status Timeout após POST Sim (idempotente) Repetir com mesma chave; se exceder, consultar recurso antes de novo envio

Observabilidade: métricas, logs estruturados e correlação

Sem visibilidade, retries viram caixa‑preta. Instrumente cada integração com métricas, logs e traços. Use correlação para seguir uma requisição ponta a ponta, do ERP ao marketplace.

Estruture logs em JSON, com chave de idempotência, correlação, tentativas, delays e estado do breaker. Veja como padronizar em logs estruturados e correlação e centralizar com Fluentd + Elasticsearch.

  • Métricas: tentativas, sucesso por operação, erros por categoria.
  • Histogramas de delay e latência end‑to‑end.
  • Gauges: estado do breaker e duração aberto.
  • Alertas por taxa de erro e saturação de rate limit.
  • Dashboards por marketplace, operação e conta.

Testes, simulação de falhas e rollout seguro

Teste retries e breaker sob falhas reais. Simule 429, 5xx, timeouts, jitter extremo e lentidão controlada. Valide que o sistema não duplica pedidos e respeita deadlines de negócio.

Implemente rollout progressivo: flags por marketplace/operação, métricas comparativas e reversão simples. Em sistemas legados, flags ajudam a ativar por conta ou rota. Veja práticas em feature flags em monólitos PHP.

  • Ambiente de sandbox do marketplace sempre que possível.
  • Testes de carga focados em picos e janelas fiscais.
  • Fault injection: derrubar DNS simulado e variar latência.
  • Canary por percentuais de contas/lojas.
  • Runbook de incidentes com passos e contatos.

Perguntas frequentes

Como decidir o número de tentativas e o intervalo do backoff?

Baseie-se na SLO da operação e nos limites do marketplace. Use poucas tentativas com backoff exponencial e jitter, limite superior de espera e deadline total. Se a janela de negócio é curta, prefira menos tentativas e fallback rápido para fila ou revisão.

Circuit breaker não esconde problemas do time?

Não, ele evita colapsos enquanto sinaliza o risco. Exponha métricas de estado, taxa de falhas e razão de abertura. Gere alertas claros para que o time atue na causa raiz. Breaker é contenção, não correção definitiva.

Como evitar duplicações ao repetir POSTs?

Implemente idempotência: gere uma chave por operação de negócio, persista resultado e responda consistentemente em reenvios. Em incerteza de status (timeout), repita com a mesma chave ou faça leitura por referência antes de reenviar. Sem idempotência, não faça retry de POST.

Devo sempre usar fila com retries e circuit breaker?

Não sempre. Fila é útil para desacoplar picos e reprocessar com controle, mas adiciona complexidade. Em integrações críticas ou de alto volume, filas ajudam. Avalie prazos, volume e SLAs do marketplace para decidir o acoplamento e padrões de reprocesso.

Quando parar de tentar e gerar erro para o usuário ou operador?

Pare quando o deadline de negócio for atingido, o número máximo de tentativas estourar ou o breaker abrir. Registre o motivo, alimente uma fila de revisão se aplicável e notifique o operador com dados para ação (erro categorizado, operação e marketplace).

Precisando revisar a resiliência das suas integrações?

Se você quer aplicar retries com backoff, idempotência e circuit breaker sem arriscar duplicações ou paralisações, vamos conversar sobre seu cenário e próximos passos.

Falar sobre integrações resilientes

Veja também