Aller au contenu principal

Health Checks

Qu'est-ce qu'un Health Check ?​

Un Health Check est un mécanisme automatique qui vérifie régulièrement si vos serveurs fonctionnent correctement. Le Load Balancer utilise ces informations pour ne diriger le trafic que vers les serveurs sains.

┌─────────────────────────────────────────────────────────────┐
│ HEALTH CHECK - CONCEPT │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ ALB │ │
│ │ │ │
│ │ Toutes les 30 secondes, vérifie : │ │
│ │ "Est-ce que /health répond 200 OK ?" │ │
│ │ │ │
│ └─────────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌─────────────┼─────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ Server │ │ Server │ │ Server │ │
│ │ 1 │ │ 2 │ │ 3 │ │
│ │ │ │ │ │ │ │
│ │ 200✓ │ │ 200✓ │ │ 503✗ │ │
│ │ HEALTHY│ │ HEALTHY│ │UNHEALTHY│ │
│ └────────┘ └────────┘ └────────┘ │
│ ↑ ↑ ✗ │
│ │ │ │ │
│ Reçoit Reçoit NE reçoit │
│ trafic trafic PAS de trafic │
│ │
└─────────────────────────────────────────────────────────────┘

Paramètres de Health Check​

Configuration​

┌─────────────────────────────────────────────────────────────┐
│ PARAMÈTRES HEALTH CHECK │
├─────────────────────────────────────────────────────────────┤
│ │
│ PARAMÈTRE │ DESCRIPTION │ DÉFAUT │
│ ───────────────────────┼──────────────────────┼──────────│
│ Protocol │ HTTP, HTTPS, TCP │ HTTP │
│ Port │ Port à vérifier │ traffic │
│ Path │ URL à tester │ / │
│ Interval │ Fréquence (sec) │ 30 │
│ Timeout │ Délai max (sec) │ 5 │
│ Healthy Threshold │ Succès pour healthy │ 3 │
│ Unhealthy Threshold │ Échecs pour unhealthy│ 2 │
│ Success Codes │ Codes HTTP OK │ 200 │
│ │
│ Exemple : │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Protocol: HTTP │ │
│ │ Port: 80 │ │
│ │ Path: /health │ │
│ │ Interval: 30s │ │
│ │ Timeout: 5s │ │
│ │ Healthy Threshold: 2 │ │
│ │ Unhealthy Threshold: 3 │ │
│ │ Success Codes: 200-299 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

Cycle de Vie d'un Target​

┌─────────────────────────────────────────────────────────────┐
│ ÉTATS D'UN TARGET │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ │
│ │ initial │ Target vient d'être enregistré │
│ └────┬─────┘ │
│ │ │
│ │ Health checks démarrent │
│ ▼ │
│ ┌──────────┐ N échecs consécutifs ┌──────────┐ │
│ │ healthy │ ────────────────────────────►│ unhealthy│ │
│ │ │ │ │ │
│ │ Reçoit │◄──────────────────────────── │ NE reçoit│ │
│ │ trafic │ N succès consécutifs │ PAS │ │
│ └──────────┘ └──────────┘ │
│ │
│ Autres états : │
│ • draining : Target en cours de désinscription │
│ • unused : Target non utilisé (pas de trafic vers lui) │
│ │
└─────────────────────────────────────────────────────────────┘

Endpoint /health​

Implémentation Recommandée​

┌─────────────────────────────────────────────────────────────┐
│ ENDPOINT /health │
├─────────────────────────────────────────────────────────────┤
│ │
│ SIMPLE (basique) │
│ ──────────────── │
│ GET /health │
│ Response: 200 OK │
│ Body: {"status": "ok"} │
│ │
│ AVANCÉ (vérifie les dépendances) │
│ ───────────────────────────────── │
│ GET /health │
│ Response: 200 OK (si tout va bien) │
│ Body: │
│ { │
│ "status": "healthy", │
│ "timestamp": "2024-01-15T10:30:00Z", │
│ "checks": { │
│ "database": "connected", │
│ "cache": "connected", │
│ "disk": "ok (75% free)" │
│ } │
│ } │
│ │
│ Response: 503 Service Unavailable (si problème) │
│ Body: │
│ { │
│ "status": "unhealthy", │
│ "checks": { │
│ "database": "connection failed", │
│ "cache": "connected", │
│ "disk": "ok" │
│ } │
│ } │
│ │
└─────────────────────────────────────────────────────────────┘

Exemples de Code​

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
});
});

Bonnes Pratiques​

Configuration Recommandée​

┌─────────────────────────────────────────────────────────────┐
│ BONNES PRATIQUES HEALTH CHECK │
├─────────────────────────────────────────────────────────────┤
│ │
│ ✅ À FAIRE │
│ ────────── │
│ • Utiliser un endpoint dédié (/health, /healthz) │
│ • Vérifier les dépendances critiques (DB, cache) │
│ • Retourner 200 seulement si vraiment healthy │
│ • Garder le health check léger et rapide │
│ • Documenter ce que le health check vérifie │
│ │
│ ❌ À ÉVITER │
│ ────────── │
│ • Utiliser la page d'accueil (/) comme health check │
│ • Health check qui fait des opérations lourdes │
│ • Toujours retourner 200 (même si problème) │
│ • Interval trop court (surcharge) │
│ • Timeout trop long (détection lente) │
│ │
│ CONFIGURATION RECOMMANDÉE : │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Interval: 30 secondes │ │
│ │ Timeout: 5 secondes │ │
│ │ Healthy Threshold: 2 │ │
│ │ Unhealthy Threshold: 3 │ │
│ │ Path: /health │ │
│ │ │ │
│ │ Temps pour détecter une panne : │ │
│ │ 3 échecs × 30s = 90 secondes max │ │
│ │ │ │
│ │ Temps pour revenir healthy : │ │
│ │ 2 succès × 30s = 60 secondes min │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

Types de Health Checks​

TypeCe qu'il vérifieQuand l'utiliser
ShallowL'app répond (200 OK)Minimum vital
DeepApp + dépendances (DB, cache)Production
LivenessL'app est vivanteKubernetes
ReadinessL'app peut recevoir du traficKubernetes

Configuration CLI​

# Créer un Target Group avec health check personnalisé
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

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

# Vérifier l'état des targets
aws elbv2 describe-target-health \
--target-group-arn arn:aws:...:tg-web

Dépannage Health Checks​

┌─────────────────────────────────────────────────────────────┐
│ DÉPANNAGE HEALTH CHECK │
├─────────────────────────────────────────────────────────────┤
│ │
│ SYMPTÔME : Target reste "unhealthy" │
│ │
│ Checklist : │
│ │
│ ☐ 1. Security Group permet le trafic du LB ? │
│ → EC2 SG doit autoriser le port depuis sg-alb │
│ │
│ ☐ 2. L'application écoute sur le bon port ? │
│ → Vérifier avec netstat -tlnp sur l'instance │
│ │
│ ☐ 3. Le path /health existe et retourne 200 ? │
│ → Tester avec curl http://localhost/health │
│ │
│ ☐ 4. Le timeout n'est pas trop court ? │
│ → Si /health est lent, augmenter timeout │
│ │
│ ☐ 5. Les codes de succès sont corrects ? │
│ → Si l'app retourne 204, l'ajouter aux success │
│ │
│ Commandes utiles : │
│ # Sur l'instance EC2 │
│ curl -v http://localhost/health │
│ netstat -tlnp | grep :80 │
│ │
│ # Depuis AWS CLI │
│ aws elbv2 describe-target-health --target-group-arn ... │
│ │
└─────────────────────────────────────────────────────────────┘

Résumé​

ParamètreValeur RecommandéeImpact
Interval30sFréquence de vérification
Timeout5sDélai max de réponse
Healthy Threshold2Retour en service rapide
Unhealthy Threshold3Évite faux positifs
Path/healthEndpoint dédié

Prochaine section : Lab Architecture HA