8-Bit Chronicles

Games • Tech • DevLog

DevLog #03 – Padrões de Resiliência: Retry, Circuit Breaker e Bulkhead

DevLog

DevLog #03 – Padrões de Resiliência: Retry, Circuit Breaker e Bulkhead

📅 Data: 20 de Janeiro de 2026

✍️ Autor: Luís Gabriel Marchió Batista


Por que Resiliência é Crítica

Em uma arquitetura serverless event-driven, falhas são inevitáveis. A chave é recuperar-se rapidamente.

1. Retry com Exponential Backoff

Não tentamos novamente imediatamente. Usamos exponential backoff:


public async Task<T> ExecuteWithRetryAsync<T>(
    Func<Task<T>> operation,
    int maxAttempts = 3)
{
    for (int attempt = 0; attempt < maxAttempts; attempt++)
    {
        try
        {
            return await operation();
        }
        catch (Exception ex) when (attempt < maxAttempts - 1)
        {
            var delay = TimeSpan.FromMilliseconds(Math.Pow(2, attempt) * 100);
            await Task.Delay(delay);
        }
    }
}

2. Circuit Breaker Pattern

Evitamos cascata de falhas parando de chamar um serviço que está falhando.


var circuitPolicy = Policy
    .Handle<HttpRequestException>()
    .OrResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
    .CircuitBreakerAsync<HttpResponseMessage>(
        handledEventsAllowedBeforeBreaking: 5,
        durationOfBreak: TimeSpan.FromSeconds(30),
        onBreak: (outcome, timespan) =>
        {
            _logger.LogWarning($"Circuit breaker aberto por {timespan.TotalSeconds}s");
        }
    );

3. Bulkhead Isolation

Isolamos recursos para que uma falha não afete todo o sistema.


var bulkheadPolicy = Policy.BulkheadAsync(
    maxParallelization: 10,
    maxQueuingActions: 5,
    onBulkheadRejectionAsync: context =>
    {
        _logger.LogWarning("Bulkhead rejeitou requisição");
        return Task.CompletedTask;
    }
);

Combinando Padrões

Combinamos esses padrões em uma Polly Policy única:


var policyWrap = Policy.WrapAsync(
    retryPolicy,
    circuitBreakerPolicy,
    bulkheadPolicy
);

Conclusão

Com esses padrões, nosso Order Pipeline pode se recuperar de falhas automaticamente e evitar cascatas de erro.