Políticas de repetição e backoff
As repetições ajudam a sobreviver a falhas temporárias, mas quando a configuração não é correta, causam avalanche de tráfego, duplicações de operações e quedas em cascata. A política de retrações confiável começa sempre com deadline/temporizadores, leva em conta a idempotação e usa backoff + jitter.
1) Princípios básicos
1. Primeiro o tempo/deadline, depois o retrai. Uma repetição sem limite de tempo só aumenta a falha.
2. Retrai - apenas para operações seguras/idumpotentes. Para os não seguros - via idempotency-keys e garantias transacionais.
3. Backoff é obrigatório. Exponencial ou GCRA, semelhante ao jitter, para dissecar as ondas.
4. Limite o número de tentativas e o orçamento-tempo total. Não deixe o SLO do usuário.
5. Respeite os sinais de infraestrutura. '429/503' + 'Retry-After', estado de circuito breaker, limites de fila.
2) Timeouts e deadline (deadline propagation)
Timeout da consulta <SLO do serviço, o deadline é distribuído para baixo na cadeia (HTTP títulos/gRPC context).
Composição de temporizadores: sumário (primeira tentativa + backoff + subsequente) ≤ deadline personalizado.
Times diferentes para leitura/gravação: gravações mais curtas e rigorosas; leituras permitem hedging.
3) Idempotidade e repetições seguras
Leitura (GET/Idumpotent RPC): repita com segurança em '5xx', 'UNAVAILABLE', timelines de rede.
Registros:- Use 'Idempotency-Key' (HTTP) ou 'request-ID' na fronteira; o servidor deve deduzir.
- Escreva «upsert», «at-least-once» + compensações (saga).
- Pagamentos/intercorrências externos - apenas com chaves idumpotentes e registros de transações.
4) Algoritmos backoff
Exponential: 'base 2 ^ attempt', limitado a' max _ backoff '.
Decorrelated Jitter (full/equal jitter): casualidade na faixa para descolonização de clientes.
GCRA/Token-Bucket-tais atrasos são alinhados com rate limits.
Limites: 'inicial _ backoff' (50-200 ms de leitura; 200-500 mc de gravação), 'max _ backoff' (1-5 s), 'max _ elapsed' (por exemplo, 3-10 s).
O modelo recomendado é backoff exponencial + full jitter.
5) Políticas de decisão «repetir/não repetir»
Repetimos quando:- Erros de rede/temporizações, '429' (respeitando 'Retry-After'), 'macios' '5xx' ('502/503/504'), gRPC 'UNAVAILABLE/DEADLINE _ EXCEEDED'.
- «4xx» (exceto «409/429/408» em alguns cenários), erros de negócio, «401/403», erros de validação, «DoNotRetry» explícito.
- '409 Conflict' é, às vezes, uma repetição com atraso após o consenso/lock.
- '404' para eventually consultent leituras - uma-duas vezes retrai com um pequeno backoff.
6) Concurrency caps e «tempestade de retrações»
Limite os retais simultâneos para-cliente/per-tenant/per-endpoint.
Limite total de tentativas de consulta (por exemplo, 2-3).
Trave os endpoits «quentes» através do controle de admissão para não inflar as filas.
7) Interação com Circuito Breaker e limites
Se o CB for aberto, não faça retais diretamente - vá para fallback ou espere 'half-open'.
Com '429' - respeite 'Retry-After'; se não estiver presente - aplique backoff «macio».
Os retais podem aumentar a carga; aplique liminares adaptativos (reduza 'max _ attempts' no incidente).
8) Protocolos e contratos
HTTP
Códigos: '408/429/5xx'.
«Retry-After», família «RateLimit -», «Idempotency-Key», «Request-Id».
O cliente deve transferir 'X-Request-Timeout '/' Deadline-At' (se for o caso).
gRPC
Use o contexto com o dedline; respeite 'UNAVAILABLE', 'DEADLINE _ EXCEEDED', pólis de retais para o método.
Para RPC Idumpotentes - inclua retais; para mutações - apenas com o apoio da idempotidade.
9) Filas, tarefas de fundo e integração
Processadores At-least-once → ações idumpotentes, dedução por chave.
Delay queue para backoff entre tentativas (por exemplo, 5s/30s/2m).
Dead-letter queue (DLQ) com limite de tentativa e processamento manual.
Outbox/CDC - para que as repetições não violem a integridade transacional.
10) Hedging vs Retries
O Hedging é útil para leituras altamente ríticas com latência de cauda.
Limite: no máximo X% de solicitações, atraso de início-grace (por exemplo, p95-laticínios), cancelamento de perdedores.
Não aplique hedging em operações de gravação sem uma forte idempotação.
11) Telemetria e observação
Теги: `tenant_id`, `endpoint`, `attempt`, `decision` (retry/skip), `reason`, `backoff_ms`, `deadline_ms`, `idempotency_key`.
Métricas: proporção de retrações, sucesso pós-retrações, p95/p99 «end-to-end», número de deadline excedidos, acionamento CB.
Logi de auditoria: N superior «ruidosas» chaves/endpoint, correlação com 429/503.
12) Testes e caos
Perfis: «sossego» (burst), «tempestade» (temporizações em massa), erros «pegajosos» (cada N-N), caudas de latência.
Falhas de estor limite/cachê/fila, clock-skew.
Verifique se a duração total (attempts + backoff) é encaixada em SLO.
13) Pseudocode de política
pseudo handle(req, deadline):
attempt = 0 backoff = initial()
while attempt < MAX_ATTEMPTS and now() < deadline:
attempt += 1 with timeout(per_attempt_timeout(deadline, attempt)):
try:
resp = call(req)
if isRetryableStatus(resp): raise Retryable(resp. status)
return resp except Retryable as e:
if circuit. isOpen(dep) or! isIdempotent(req): break sleep(jitter(backoff))
backoff = min(exp(backoff), MAX_BACKOFF)
except NonRetryable:
break return fail_or_fallback(req)
14) Modelo de configuração (exemplo)
yaml retries:
default:
max_attempts: 3 initial_backoff_ms: 150 max_backoff_ms: 2000 strategy: exponential_full_jitter respect_retry_after: true per_attempt_timeout_fraction: 0. 4 # 40% of remaining deadline hedging:
enabled: false read_heavy:
max_attempts: 4 initial_backoff_ms: 80 max_backoff_ms: 1200 hedging:
enabled: true start_after_p95_ms: 300 max_extra_requests_ratio: 0. 05 write_strict:
max_attempts: 2 initial_backoff_ms: 250 max_backoff_ms: 1000 idempotency_required: true
limits:
concurrent_retries_per_tenant: 100 concurrent_retries_per_endpoint: 20
15) Folha de cheque antes de vender
- Os deadline se espalham através de chamadas; duração total de ≤ SLO.
- Algoritmo backoff com jitter; os parâmetros são validados por um teste de carga.
- Idempotidade: chaves/registros/compensações.
- As políticas de retração variam para leituras e registros; respect `Retry-After`.
- A concorrência de retrações e o número total de tentativas são limitados.
- A integração com circuito breaker e rate limits está configurada.
- Telemetria: tags, métricas, logs de causa; dashbords p95/p99, uma proporção de sucesso após os retrações.
- Testes de «tempestades» e caudas de latência, DLQ para tarefas.
- Documentação para clientes: códigos/títulos, exemplos de backoff e cancelamentos.
16) Erros típicos
Repetições sem temporizações/deadline são «eternas expectativas».
Pausas fixas sem jitter - ondas sincronizadas e auto-montagem DDoS.
Retraias de gravações inseguras sem idempotidade - duplos e rascronização.
Ignorar 'Retry-After' e sinais CB - escalar o incidente.
Espaço apertado nas filas por falta de caps e de controle de adesão.
A falta de telemetria de causas/soluções de retrações é «voo cego».
17) Receitas rápidas
Leitura pública de API: 3 tentativas, 'inicial = 100ms', 'max = 1s', full jitter, hedging até 5% do tráfego.
Registros críticos (pagamento): 1-2 tentativas max, tempo rigoroso, obrigatório 'Idempotency-Key', sem hedging.
Integração externa: respeitar '429/Retry-After', 'max _ attempts = 3', 'max _ backoff = 2-5s', limites para o fluxo de saída.
Tarefas de fundo: delay-backoff (5s → 30s → 2m), DLQ, processadores de idumpotentes.
Conclusão
Uma boa política de repetição é o equilíbrio entre uma recuperação rápida e uma rejeição controlada. Dedline, idempotidade, backoff exponencial com jitter, restrição de competição e respeito aos sinais de infraestrutura transformam os retais de «tempestade» em ferramenta para aumentar a confiabilidade e retenção do SLO.