Estratégias de deploy zero-downtime em produção

1. Fundamentos do Deploy Zero-Downtime

O deploy zero-downtime é uma abordagem que permite atualizar sistemas em produção sem interromper o serviço aos usuários. O objetivo principal é garantir que a aplicação permaneça disponível durante todo o ciclo de implantação, mantendo os SLAs (Service Level Agreements) e SLOs (Service Level Objectives) estabelecidos. As métricas de sucesso típicas incluem tempo de resposta abaixo de 200ms, taxa de erro inferior a 0,1% e disponibilidade de 99,99%.

Os desafios mais comuns envolvem:
- Estado de sessão: usuários logados perdem contexto quando instâncias são recicladas
- Migrações de banco de dados: alterações de schema que quebram a versão antiga
- Consistência de cache: dados desatualizados servidos após mudanças no backend

As três abordagens principais são: rolling update (atualização gradual), blue-green (troca completa de ambiente) e canary (liberação progressiva). Cada uma tem trade-offs específicos em termos de custo, complexidade e segurança.

2. Estratégia Rolling Update

O rolling update substitui gradualmente instâncias da aplicação, uma a uma ou em pequenos lotes, mantendo a capacidade total durante o processo. A configuração de health checks é crítica:

# Configuração de readiness probe (Kubernetes)
readinessProbe:
  httpGet:
    path: /health/ready
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 5
  failureThreshold: 3

# Configuração de liveness probe
livenessProbe:
  httpGet:
    path: /health/live
    port: 8080
  initialDelaySeconds: 30
  periodSeconds: 10
  failureThreshold: 3

O readiness probe garante que apenas pods saudáveis recebam tráfego, enquanto o liveness probe reinicia pods com falhas. O rollback automático é acionado quando a nova versão não atinge o número mínimo de réplicas saudáveis:

# Configuração de rolling update no deployment
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 25%
    maxUnavailable: 25%

3. Estratégia Blue-Green Deployment

Esta estratégia mantém dois ambientes completos: blue (atual) e green (nova versão). O balanceador de carga direciona todo o tráfego para o ambiente blue enquanto o green é preparado. Após validação, o tráfego é trocado instantaneamente:

# Configuração de balanceador Nginx para blue-green
upstream backend {
    server blue-cluster:8080 weight=100;
    server green-cluster:8080 weight=0;
}

# Troca de tráfego via script
#!/bin/bash
sed -i 's/weight=100/weight=0/g' /etc/nginx/conf.d/backend.conf
sed -i 's/weight=0/weight=100/g' /etc/nginx/conf.d/backend.conf
nginx -s reload

A limpeza pós-deploy requer remoção segura do ambiente antigo após confirmação de estabilidade. O custo de infraestrutura dobra durante a transição, mas o rollback é instantâneo.

4. Estratégia Canary Release

O canary release roteia uma pequena porcentagem de tráfego para a nova versão, permitindo monitoramento de métricas antes da liberação completa:

# Configuração de service mesh (Istio) para canary
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: app-canary
spec:
  hosts:
  - app.example.com
  http:
  - route:
    - destination:
        host: app
        subset: stable
      weight: 95
    - destination:
        host: app
        subset: canary
      weight: 5

Métricas monitoradas incluem latência (p95 < 300ms), taxa de erro (< 0,5%) e logs de exceção. A aprovação gradual pode ser automatizada com base em limites predefinidos.

5. Tratamento de Estado e Dados

Migrações de banco de dados sem downtime exigem backward compatibility e versionamento de schema:

# Técnica de backward compatibility
-- Adicionar coluna como nullable
ALTER TABLE users ADD COLUMN phone VARCHAR(20) NULL;

-- Migração em duas fases
-- Fase 1: código lê e escreve ambos os formatos
-- Fase 2: após deploy, coluna se torna NOT NULL
ALTER TABLE users MODIFY COLUMN phone VARCHAR(20) NOT NULL;

Para gerenciamento de sessão, use armazenamento externo como Redis:

# Configuração de sessão externa no Spring Boot
spring.session.store-type=redis
spring.redis.host=redis-cluster.example.com
spring.redis.port=6379

Cache e filas requerem estratégias de invalidação durante o deploy, como TTL reduzido ou drenagem manual de filas.

6. Automação e Integração Contínua

Um pipeline CI/CD para deploy zero-downtime inclui estágios de build, teste e aprovação:

# Pipeline GitLab CI/CD
stages:
  - build
  - test
  - deploy-canary
  - promote

build:
  stage: build
  script:
    - docker build -t app:${CI_COMMIT_SHA} .
    - docker push registry.example.com/app:${CI_COMMIT_SHA}

test:
  stage: test
  script:
    - docker-compose -f docker-compose.test.yml up --abort-on-container-exit
    - npm run test:integration
    - npm run test:load

deploy-canary:
  stage: deploy-canary
  script:
    - kubectl set image deployment/app-canary app=registry.example.com/app:${CI_COMMIT_SHA}
    - sleep 300  # Monitoramento de 5 minutos
  only:
    - main

promote:
  stage: promote
  script:
    - kubectl set image deployment/app app=registry.example.com/app:${CI_COMMIT_SHA}
  when: manual

7. Monitoramento e Observabilidade

Métricas-chave durante o deploy incluem tempo de resposta, taxa de sucesso e uso de recursos:

# Configuração de alerta no Prometheus
groups:
  - name: deploy-alerts
    rules:
      - alert: HighErrorRateDuringDeploy
        expr: |
          rate(http_requests_total{status=~"5.."}[5m]) / 
          rate(http_requests_total[5m]) > 0.01
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "Erro alto durante deploy"

Dashboards no Grafana devem exibir comparações entre versões antiga e nova, além de métricas de banco de dados e cache.

Referências