Por que seu serviço não deve "parar" na hora do almoço?
Imagine: sexta-feira, 18:45. Você acabou de lançar a tão esperada atualização do serviço C#. E imediatamente o chat de suporte recebe mensagens: "site não funciona", "erro 503", "perdi dados do carrinho". Familiar? Este é o cenário clássico onde um deploy "na marra" destrói a experiência do usuário. No mundo moderno, onde cada hora de inatividade pode custar milhões, deploy zero-downtime de serviços C# não é um luxo, mas uma higiene básica de desenvolvimento.
Neste artigo, não vamos ler palestras chatas. Vamos analisar estratégias reais de atualização de aplicações .NET sem interromper o funcionamento, escrever código de health checks e graceful shutdown, e mostrar como configurar rolling update no Kubernetes. Se você está cansado de quedas "mágicas" da produção após cada commit — este material é para você. Vamos nessa!
O que é zero-downtime deployment e por que ele é importante para o desenvolvedor C#?
Zero-downtime deployment (deploy com tempo de inatividade zero) é uma metodologia de atualização de aplicação onde a versão antiga continua atendendo requisições até que a nova versão esteja completamente operacional. O usuário não percebe a troca: nem erros, nem timeouts, nem perda de sessão.
Principais problemas ao atualizar serviços C#
- Graceful shutdown nem sempre funciona. O padrão
app.StopAsync()pode interromper requisições ativas se os timeouts não forem configurados. - Conexões pendentes. A versão antiga mantém WebSockets abertos ou requisições HTTP longas.
- Migrações de BD. A nova versão exige alterações no esquema, mas a antiga é incompatível com elas.
- Cache e sessões. Após a troca, o usuário perde dados na memória.
A boa notícia: C# e o ecossistema .NET fornecem todas as ferramentas para resolver esses problemas. Nossa tarefa é reuni-las em um sistema funcional.
Estratégia nº 1: Blue-Green Deployment para C#
Este é o esquema mais simples e confiável. Você tem dois ambientes idênticos: Blue (versão atual) e Green (nova versão). Você implanta a nova versão no Green, executa smoke-tests e, em seguida, alterna instantaneamente o balanceador de carga do Blue para o Green. Se algo der errado, você reverte em segundos.
Como implementar isso para .NET?
Precisamos de um balanceador de carga (NGINX, HAProxy ou Load Balancer em nuvem) e duas instâncias do seu serviço C#. Exemplo de configuração do NGINX:
upstream backend { server blue-server:5000 weight=100; server green-server:5000 weight=0; # Reserva}
server { listen 80; location / { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; }}Após implantar a versão Green, alteramos os pesos: blue:0, green:100. Os usuários migram imperceptivelmente para a nova versão.
Vantagens: simplicidade, reversão instantânea.
Desvantagens: necessidade do dobro de recursos (servidores).
Estratégia nº 2: Rolling Update com Kubernetes (ideal para microsserviços)
O Kubernetes faz rolling update "de fábrica". Ele substitui gradualmente os Pods antigos pelos novos, sem interromper o tráfego. Mas para que funcione corretamente com C#, é necessário configurar health probes e graceful shutdown.
Health Checks no .NET 6/8
Adicione ao seu Program.cs um endpoint para verificar prontidão (readiness) e vitalidade (liveness):
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthChecks() .AddCheck<DatabaseHealthCheck>("database") .AddCheck<CacheHealthCheck>("redis");
var app = builder.Build();
app.MapHea