Saltar al contenido principal

Health Checks

¿Qué es un Health Check?​

Un Health Check es un mecanismo automático que verifica regularmente si sus servidores funcionan correctamente. El Load Balancer utiliza esta información para dirigir el tráfico solo a los servidores saludables.

┌─────────────────────────────────────────────────────────────┐
│ HEALTH CHECK - CONCEPTO │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ ALB │ │
│ │ │ │
│ │ Cada 30 segundos, verifica: │ │
│ │ "¿Responde /health con 200 OK?" │ │
│ │ │ │
│ └─────────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌─────────────┼─────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ Server │ │ Server │ │ Server │ │
│ │ 1 │ │ 2 │ │ 3 │ │
│ │ │ │ │ │ │ │
│ │ 200✓ │ │ 200✓ │ │ 503✗ │ │
│ │ HEALTHY│ │ HEALTHY│ │UNHEALTHY│ │
│ └────────┘ └────────┘ └────────┘ │
│ ↑ ↑ ✗ │
│ │ │ │ │
│ Recibe Recibe NO recibe │
│ tráfico tráfico tráfico │
│ │
└─────────────────────────────────────────────────────────────┘

Parámetros de Health Check​

Configuración​

┌─────────────────────────────────────────────────────────────┐
│ PARÁMETROS HEALTH CHECK │
├─────────────────────────────────────────────────────────────┤
│ │
│ PARÁMETRO │ DESCRIPCIÓN │ POR DEFECTO│
│ ───────────────────────┼─────────────────────┼───────────│
│ Protocol │ HTTP, HTTPS, TCP │ HTTP │
│ Port │ Puerto a verificar │ traffic │
│ Path │ URL a probar │ / │
│ Interval │ Frecuencia (seg) │ 30 │
│ Timeout │ Tiempo máx (seg) │ 5 │
│ Healthy Threshold │ Éxitos para healthy │ 3 │
│ Unhealthy Threshold │ Fallos para unhealthy│ 2 │
│ Success Codes │ Códigos HTTP OK │ 200 │
│ │
│ Ejemplo: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Protocol: HTTP │ │
│ │ Port: 80 │ │
│ │ Path: /health │ │
│ │ Interval: 30s │ │
│ │ Timeout: 5s │ │
│ │ Healthy Threshold: 2 │ │
│ │ Unhealthy Threshold: 3 │ │
│ │ Success Codes: 200-299 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

Ciclo de Vida de un Target​

┌─────────────────────────────────────────────────────────────┐
│ ESTADOS DE UN TARGET │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ │
│ │ initial │ Target acaba de ser registrado │
│ └────┬─────┘ │
│ │ │
│ │ Inician los health checks │
│ ▼ │
│ ┌──────────┐ N fallos consecutivos ┌──────────┐ │
│ │ healthy │ ────────────────────────────►│ unhealthy│ │
│ │ │ │ │ │
│ │ Recibe │◄──────────────────────────── │ NO recibe│ │
│ │ tráfico │ N éxitos consecutivos │ │ │
│ └──────────┘ └──────────┘ │
│ │
│ Otros estados: │
│ • draining : Target en proceso de desregistro │
│ • unused : Target no usado (sin tráfico dirigido a él) │
│ │
└─────────────────────────────────────────────────────────────┘

Endpoint /health​

Implementación Recomendada​

┌─────────────────────────────────────────────────────────────┐
│ ENDPOINT /health │
├─────────────────────────────────────────────────────────────┤
│ │
│ SIMPLE (básico) │
│ ──────────────── │
│ GET /health │
│ Response: 200 OK │
│ Body: {"status": "ok"} │
│ │
│ AVANZADO (verifica dependencias) │
│ ───────────────────────────────── │
│ GET /health │
│ Response: 200 OK (si todo está bien) │
│ Body: │
│ { │
│ "status": "healthy", │
│ "timestamp": "2024-01-15T10:30:00Z", │
│ "checks": { │
│ "database": "connected", │
│ "cache": "connected", │
│ "disk": "ok (75% free)" │
│ } │
│ } │
│ │
│ Response: 503 Service Unavailable (si hay problema) │
│ Body: │
│ { │
│ "status": "unhealthy", │
│ "checks": { │
│ "database": "connection failed", │
│ "cache": "connected", │
│ "disk": "ok" │
│ } │
│ } │
│ │
└─────────────────────────────────────────────────────────────┘

Ejemplos de Código​

Python (Flask):

from flask import Flask, jsonify
import psycopg2

app = Flask(__name__)

@app.route('/health')
def health_check():
checks = {}
is_healthy = True

# Vérifier la base de données
try:
conn = psycopg2.connect(DATABASE_URL)
conn.close()
checks['database'] = 'connected'
except Exception as e:
checks['database'] = f'failed: {str(e)}'
is_healthy = False

# Vérifier le cache Redis
try:
redis_client.ping()
checks['redis'] = 'connected'
except:
checks['redis'] = 'failed'
is_healthy = False

status_code = 200 if is_healthy else 503
return jsonify({
'status': 'healthy' if is_healthy else 'unhealthy',
'checks': checks
}), status_code

Node.js (Express):

app.get('/health', async (req, res) => {
const checks = {};
let isHealthy = true;

// Vérifier la DB
try {
await db.query('SELECT 1');
checks.database = 'connected';
} catch (e) {
checks.database = 'failed';
isHealthy = false;
}

const statusCode = isHealthy ? 200 : 503;
res.status(statusCode).json({
status: isHealthy ? 'healthy' : 'unhealthy',
checks
});
});

Buenas Prácticas​

Configuración Recomendada​

┌─────────────────────────────────────────────────────────────┐
│ BUENAS PRÁCTICAS HEALTH CHECK │
├─────────────────────────────────────────────────────────────┤
│ │
│ ✅ QUÉ HACER │
│ ────────── │
│ • Usar un endpoint dedicado (/health, /healthz) │
│ • Verificar dependencias críticas (DB, cache) │
│ • Retornar 200 solo si realmente está healthy │
│ • Mantener el health check ligero y rápido │
│ • Documentar lo que verifica el health check │
│ │
│ ❌ QUÉ EVITAR │
│ ────────── │
│ • Usar la página principal (/) como health check │
│ • Health check que realiza operaciones pesadas │
│ • Retornar siempre 200 (aunque haya problema) │
│ • Intervalo demasiado corto (sobrecarga) │
│ • Timeout demasiado largo (detección lenta) │
│ │
│ CONFIGURACIÓN RECOMENDADA: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Interval: 30 segundos │ │
│ │ Timeout: 5 segundos │ │
│ │ Healthy Threshold: 2 │ │
│ │ Unhealthy Threshold: 3 │ │
│ │ Path: /health │ │
│ │ │ │
│ │ Tiempo para detectar una falla: │ │
│ │ 3 fallos × 30s = 90 segundos máx │ │
│ │ │ │
│ │ Tiempo para volver a healthy: │ │
│ │ 2 éxitos × 30s = 60 segundos mín │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

Tipos de Health Checks​

TipoQué verificaCuándo usarlo
ShallowLa app responde (200 OK)Mínimo vital
DeepApp + dependencias (DB, cache)Producción
LivenessLa app está vivaKubernetes
ReadinessLa app puede recibir tráficoKubernetes

Configuración CLI​

# Crear un Target Group con health check personalizado
aws elbv2 create-target-group \
--name tg-web-healthy \
--protocol HTTP \
--port 80 \
--vpc-id vpc-xxx \
--health-check-protocol HTTP \
--health-check-port 80 \
--health-check-path /health \
--health-check-interval-seconds 30 \
--health-check-timeout-seconds 5 \
--healthy-threshold-count 2 \
--unhealthy-threshold-count 3 \
--matcher HttpCode=200-299

# Modificar un health check existente
aws elbv2 modify-target-group \
--target-group-arn arn:aws:...:tg-web \
--health-check-path /api/health \
--health-check-interval-seconds 15

# Verificar el estado de los targets
aws elbv2 describe-target-health \
--target-group-arn arn:aws:...:tg-web

Resolución de Problemas Health Checks​

┌─────────────────────────────────────────────────────────────┐
│ RESOLUCIÓN DE PROBLEMAS HEALTH CHECK │
├─────────────────────────────────────────────────────────────┤
│ │
│ SÍNTOMA: Target permanece "unhealthy" │
│ │
│ Checklist: │
│ │
│ ☐ 1. ¿El Security Group permite tráfico del LB? │
│ → El SG de EC2 debe autorizar el puerto desde sg-alb│
│ │
│ ☐ 2. ¿La aplicación escucha en el puerto correcto? │
│ → Verificar con netstat -tlnp en la instancia │
│ │
│ ☐ 3. ¿El path /health existe y retorna 200? │
│ → Probar con curl http://localhost/health │
│ │
│ ☐ 4. ¿El timeout no es demasiado corto? │
│ → Si /health es lento, aumentar el timeout │
│ │
│ ☐ 5. ¿Los códigos de éxito son correctos? │
│ → Si la app retorna 204, añadirlo a los success │
│ │
│ Comandos útiles: │
│ # En la instancia EC2 │
│ curl -v http://localhost/health │
│ netstat -tlnp | grep :80 │
│ │
│ # Desde AWS CLI │
│ aws elbv2 describe-target-health --target-group-arn ... │
│ │
└─────────────────────────────────────────────────────────────┘

Resumen​

ParámetroValor RecomendadoImpacto
Interval30sFrecuencia de verificación
Timeout5sTiempo máx de respuesta
Healthy Threshold2Retorno rápido a servicio
Unhealthy Threshold3Evita falsos positivos
Path/healthEndpoint dedicado

Próxima sección: Lab Arquitectura HA