Estrategias de implementación sin tiempo de inactividad: mantenga su aplicación en funcionamiento durante las actualizaciones

Implemente implementaciones sin tiempo de inactividad con estrategias azul-verde, continuas y canarias. Cubre migraciones de bases de datos, controles de estado y patrones de reversión automatizados.

E
ECOSIRE Research and Development Team
|16 de marzo de 20267 min de lectura1.6k Palabras|

Estrategias de implementación sin tiempo de inactividad: mantenga su aplicación en funcionamiento durante las actualizaciones

El tiempo de inactividad planificado cuesta a las empresas un promedio de $5600 por minuto. Sin embargo, el 43% de las empresas todavía desconectan sus aplicaciones durante las implementaciones. La implementación sin tiempo de inactividad no es un lujo, es una expectativa. Los clientes, los motores de búsqueda y los socios de integración penalizan las aplicaciones que se desconectan, aunque sea brevemente.

Esta guía cubre las tres estrategias principales de implementación sin tiempo de inactividad, técnicas de migración de bases de datos que preservan el tiempo de actividad y mecanismos de reversión automatizados.

Conclusiones clave

  • La implementación azul-verde es la estrategia más segura: reversión instantánea cambiando el tráfico a la versión anterior
  • Las migraciones de bases de datos deben ser compatibles con versiones anteriores: la versión anterior de la aplicación debe funcionar con el nuevo esquema.
  • Las comprobaciones de estado y las sondas de preparación evitan enrutar el tráfico a pods que no están listos para servir.
  • La reversión automatizada basada en el monitoreo de la tasa de errores reduce el tiempo medio de recuperación a menos de 2 minutos

Comparación de estrategias

EstrategiaComplejidadVelocidad de retrocesoCosto de infraestructuraMejor para
Azul verdosoBajoInstantáneo (segundos)2x durante el despliegueAplicaciones críticas, implementaciones poco frecuentes
Actualización continuaMedioMinutos1,25x durante la implementaciónKubernetes, despliegues frecuentes
CanariasAltoRápido (segundos)1,05x durante la implementaciónAlto tráfico, sensible al riesgo
Banderas de característicasMedioInstantáneo1xLanzamiento gradual de funciones

Despliegue azul-verde

Arquitectura

Load Balancer
    |
    |--- [ACTIVE] Blue environment (v2.0.0) <-- receives 100% traffic
    |
    |--- [IDLE] Green environment (v2.1.0) <-- deployed, tested, waiting

En implementación:

  1. Implementar v2.1.0 en el entorno inactivo (verde)
  2. Realice pruebas de humo contra el verde.
  3. Cambie el equilibrador de carga a verde
  4. El azul queda inactivo (disponible para reversión instantánea)

Implementación con Nginx

# /etc/nginx/conf.d/app.conf
upstream blue {
    server 10.0.1.10:3000;
    server 10.0.1.11:3000;
}

upstream green {
    server 10.0.2.10:3000;
    server 10.0.2.11:3000;
}

# Active environment - change this during deployment
map $host $active_upstream {
    default blue;  # Change to 'green' to switch
}

server {
    listen 443 ssl;
    server_name app.example.com;

    location / {
        proxy_pass http://$active_upstream;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Script de implementación

#!/bin/bash
set -e

CURRENT=$(cat /etc/nginx/active-env)  # "blue" or "green"
TARGET=$( [ "$CURRENT" = "blue" ] && echo "green" || echo "blue" )

echo "Current: $CURRENT, deploying to: $TARGET"

# Deploy to inactive environment
ssh "deploy@$TARGET-1" "cd /opt/app && git pull && pnpm install --frozen-lockfile && pnpm build && pm2 restart all"
ssh "deploy@$TARGET-2" "cd /opt/app && git pull && pnpm install --frozen-lockfile && pnpm build && pm2 restart all"

# Wait for health checks
for i in 1 2; do
  echo "Checking $TARGET-$i health..."
  for attempt in $(seq 1 30); do
    if curl -sf "http://$TARGET-$i:3000/health" > /dev/null; then
      echo "$TARGET-$i is healthy"
      break
    fi
    sleep 2
  done
done

# Run smoke tests
pnpm test:smoke --base-url "http://$TARGET-1:3000"

# Switch traffic
sed -i "s/default $CURRENT/default $TARGET/" /etc/nginx/conf.d/app.conf
nginx -s reload
echo "$TARGET" > /etc/nginx/active-env

echo "Traffic switched to $TARGET. Rollback: change active-env back to $CURRENT"

Actualización continua

Las actualizaciones continuas reemplazan las instancias de forma incremental, lo que garantiza que siempre haya algo de capacidad disponible.

Actualización continua de Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # Create 1 extra pod during update
      maxUnavailable: 0   # Never reduce below desired replicas
  template:
    spec:
      containers:
        - name: api
          image: registry.example.com/api:v2.1.0
          readinessProbe:
            httpGet:
              path: /health
              port: 3001
            initialDelaySeconds: 5
            periodSeconds: 5
          livenessProbe:
            httpGet:
              path: /health
              port: 3001
            initialDelaySeconds: 15
            periodSeconds: 10

El proceso de actualización continua con maxSurge: 1 y maxUnavailable: 0:

  1. Cree 1 pod nuevo con v2.1.0 (6 pods en total: 5 antiguos + 1 nuevo)
  2. Espere a que pase la nueva sonda de preparación del módulo.
  3. Terminar 1 módulo antiguo (5 módulos: 4 antiguos + 1 nuevo)
  4. Cree otro pod nuevo (6 pods: 4 antiguos + 2 nuevos)
  5. Repita hasta que todos los pods sean v2.1.0

Implementación canaria

División del tráfico

# Istio VirtualService for canary routing
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: api-canary
spec:
  hosts:
    - api.example.com
  http:
    - route:
        - destination:
            host: api-stable
            port:
              number: 3001
          weight: 95
        - destination:
            host: api-canary
            port:
              number: 3001
          weight: 5

Lanzamiento progresivo de Canarias

FaseTráfico CanariasDuraciónCriterios de éxito
11%10 minutosTasa de error <0,1 %, latencia <500 ms
25%30 minutosTasa de error <0,1 %, latencia <500 ms
325%1 horaTasa de error <0,5 %, latencia <1 s
450%2 horasTasa de error <0,5 %, latencia <1 s
5100%Lanzamiento completoEstable durante 24 horas

Migraciones de bases de datos sin tiempo de inactividad

El mayor desafío en la implementación sin tiempo de inactividad son los cambios en el esquema de la base de datos. La versión anterior de la aplicación debe funcionar con el nuevo esquema y viceversa.

El patrón de expansión-contrato

Fase 1: Expandir (implementar cambio de esquema)

-- Add new column (nullable, no default)
ALTER TABLE orders ADD COLUMN shipping_method VARCHAR(50);

El código de aplicación antiguo ignora la nueva columna. El nuevo código de la aplicación escribe en columnas nuevas y antiguas.

Fase 2: Migrar datos

-- Backfill existing data
UPDATE orders SET shipping_method = 'standard' WHERE shipping_method IS NULL;

Fase 3: Contrato (implementar código que utiliza exclusivamente la nueva columna)

Después de que todas las instancias de la aplicación utilicen la nueva columna:

-- Make column required
ALTER TABLE orders ALTER COLUMN shipping_method SET NOT NULL;
ALTER TABLE orders ALTER COLUMN shipping_method SET DEFAULT 'standard';

Patrones de migración peligrosos

PatrónRiesgoAlternativa segura
Cambiar nombre de columnaRompe el código antiguoAgregar nueva columna, migrar, eliminar la anterior
Columna de caídaRompe el código antiguoDeje de usarlo y luego ingrese la próxima versión
Agregar columna NO NULAMesa de cerradurasAgregue valores anulables, rellene, modifique a NOT NULL
Cambiar tipo de columnaBloquea la tabla, rompe las consultasAgregar nueva columna con nuevo tipo, migrar
Agregar índice únicoBloquea la mesa en mesas grandesCÓDIGO0

Reversión automatizada

Reversión basada en tasa de error

#!/bin/bash
# post-deploy-monitor.sh

DEPLOY_TIME=$(date +%s)
MONITOR_DURATION=300  # 5 minutes
ERROR_THRESHOLD=0.02  # 2%

while [ $(($(date +%s) - DEPLOY_TIME)) -lt $MONITOR_DURATION ]; do
  ERROR_RATE=$(curl -s "http://prometheus:9090/api/v1/query?query=rate(http_requests_total{status=~'5..'}[2m])/rate(http_requests_total[2m])" | jq -r '.data.result[0].value[1]')

  if (( $(echo "$ERROR_RATE > $ERROR_THRESHOLD" | bc -l) )); then
    echo "ERROR: Rate $ERROR_RATE exceeds threshold $ERROR_THRESHOLD"
    echo "Initiating rollback..."
    kubectl rollout undo deployment/api
    exit 1
  fi

  sleep 15
done

echo "Deployment healthy for $MONITOR_DURATION seconds"

Preguntas frecuentes

¿Con qué estrategia deberíamos empezar?

Comience con la implementación azul-verde. Es el más sencillo de implementar, proporciona una reversión instantánea y funciona con cualquier arquitectura de aplicación. Las actualizaciones continuas son mejores para entornos de Kubernetes con muchas réplicas. Las implementaciones Canary son para aplicaciones con mucho tráfico en las que desea validar los cambios con tráfico real antes de la implementación completa.

¿Cómo manejamos los trabajos en segundo plano de larga duración durante la implementación?

Utilice un cierre elegante. Cuando un pod recibe una señal de finalización, deja de aceptar nuevos trabajos, finaliza los trabajos en curso (con un tiempo de espera) y luego apágalo. En Kubernetes, configure terminationGracePeriodSeconds para permitir tiempo suficiente para que se completen los trabajos. Para trabajos que toman más tiempo que el período de gracia, use una cola de trabajos (Redis, RabbitMQ) que reintenta trabajos fallidos con los trabajadores supervivientes.

¿Qué pasa con las conexiones WebSocket durante la implementación?

Las conexiones WebSocket son duraderas y deben manejarse con cuidado. Durante una actualización continua, las conexiones existentes en el pod antiguo permanecen activas hasta que finaliza el pod. Los clientes deben implementar una lógica de reconexión automática. Para implementaciones azul-verde, cambie las nuevas conexiones al nuevo entorno y permita que las conexiones existentes se agoten en el entorno anterior con un tiempo de espera.

¿Cómo probamos implementaciones sin tiempo de inactividad?

Ejecute una prueba de carga durante la implementación. Utilice k6 o una herramienta similar para generar tráfico continuo y luego active una implementación. Verifique si hay errores, aumento de latencia o conexiones caídas durante la transferencia. Consulte nuestra guía de pruebas de carga para obtener detalles de implementación.


¿Qué viene después?

La implementación sin tiempo de inactividad es un requisito previo para lanzamientos frecuentes y seguros. Combínelo con automatización de CI/CD para el proceso de implementación completo y monitoreo para la verificación posterior a la implementación.

Comuníquese con ECOSIRE para obtener consultoría sobre estrategia de implementación, o explore nuestra guía DevOps para obtener la hoja de ruta completa de infraestructura.


Publicado por ECOSIRE: ayuda a las empresas a implementar sin interrupciones.

E

Escrito por

ECOSIRE Research and Development Team

Construyendo productos digitales de nivel empresarial en ECOSIRE. Compartiendo perspectivas sobre integraciones Odoo, automatización de eCommerce y soluciones empresariales impulsadas por IA.

Chatea en whatsapp