O que são Canary Deployments e por que isso salvará sua produção?
\nVocê já implantou uma atualização à meia-noite, rezando para que nada quebrasse? Familiar. E se eu disser que você pode testar código novo em usuários reais, mas de forma que ninguém seja prejudicado? Estamos falando de canary deployments — uma estratégia de implantação onde a nova versão da aplicação recebe inicialmente apenas uma pequena parte do tráfego. Se tudo estiver bem — o tráfego aumenta. Se não — reversão em segundos.
\nNo mundo .NET e C# isso é especialmente relevante: microsserviços, altas cargas, requisitos de estabilidade. Vamos escrever código, configurar canary deployment e analisar exemplos reais. Vamos lá!
\n\nPor que Canary não é apenas uma palavra da moda?
\nO tradicional blue-green deployment alterna todo o tráfego de uma vez. Rolling update — gradualmente, mas sem controle fino. Canary dá a você um superpoder: você lança uma nova versão, mas direciona para ela, digamos, 5% dos usuários. Os outros 95% trabalham na versão estável antiga. Você monitora métricas, erros, latências. Se tudo estiver ok — aumenta gradualmente a porcentagem para 100. Se não — simplesmente desliga o canary.
\nPara o desenvolvedor C#, isso é especialmente conveniente: podemos usar ferramentas nativas do ASP.NET Core, Kubernetes, Feature Flags ou até mesmo um simples balanceador de carga. O principal é a arquitetura correta.
\n\nArquitetura de Canary Deployment para aplicação .NET
\nVamos imaginar que temos uma Web API em ASP.NET Core que processa pedidos. Queremos lançar uma nova lógica de cálculo de descontos. Em vez de atualizar todos os pods de uma vez, nós:
\n- \n
- Iniciamos duas versões do serviço: stable (v1) e canary (v2). \n
- Configuramos o balanceador (ex: Nginx ou Kubernetes Service) para que 95% do tráfego vá para v1 e 5% para v2. \n
- Adicionamos o cabeçalho HTTP
X-Canary: truenas respostas da versão canary para identificação. \n - Coletamos métricas (código 200/500, latência, quantidade de pedidos). \n
- Se em 30 minutos os erros não forem maiores que na v1, aumentamos o peso do canary para 50%, depois para 100%. \n
Implementação em C#: do simples ao complexo
\n\nMétodo 1: Canary via cabeçalhos HTTP e balanceador
\nO caminho mais simples é usar uma camada de middleware no ASP.NET Core que marca as requisições. Mas primeiro, vamos ver como fica o código que diferencia a versão canary.
\n// Startup.cs ou Program.cs\npublic class CanaryMiddleware\n{\n private readonly RequestDelegate _next;\n private readonly string _version;\n\n public CanaryMiddleware(RequestDelegate next, string version)\n {\n _next = next;\n _version = version;\n }\n\n public async Task InvokeAsync(HttpContext context)\n {\n // Adiciona cabeçalho para identificação da versão\n context.Response.Headers.Add("X-App-Version", _version);\n await _next(context);\n }\n}\n\n// Registro\napp.UseMiddleware<CanaryMiddleware>("v2-canary");\n\nAgora, no nível do balanceador (ex: Nginx), decidimos qual porcentagem de tráfego enviar para o pod canary:
\nupstream backend {\n server app-stable:5000 weight=95;\n server app-canary:5000 weight=5;\n}\n\nPrós: simplicidade. Contras: sem controle programático, difícil fazer teste A/B por usuário.
\n\nMétodo 2: Feature Flags em C#
\nUma abordagem mais flexível é usar feature flags (flags de funcionalidade). Você ativa a nova lógica apenas para um grupo específico de usuários. O ASP.NET Core tem suporte nativo:
\n// Instale o pacote Microsoft.FeatureManagement.AspNetCore\n// Adicione em Program.cs\nbuilder.Services.AddFeatureManagement();\n\n// Defina a flag em appsettings.json\n{\n "FeatureManagement": {\n "NewDiscountLogic": false\n }\n}\n\n// Use no controller\n[ApiController]\n[Route