الفحوصات الصحية
ما هو الفحص الصحي؟
الفحص الصحي هو آلية تلقائية تتحقق بانتظام مما إذا كانت الخوادم تعمل بشكل صحيح. يستخدم موازن التحميل هذه المعلومات لتوجيه الحركة فقط إلى الخوادم السليمة.
┌─────────────────────────────────────────────────────────────┐
│ HEALTH CHECK - CONCEPT │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ ALB │ │
│ │ │ │
│ │ كل 30 ثانية، يتحقق: │ │
│ │ "هل /health يستجيب بـ 200 OK؟" │ │
│ │ │ │
│ └─────────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌─────────────┼─────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ Server │ │ Server │ │ Server │ │
│ │ 1 │ │ 2 │ │ 3 │ │
│ │ │ │ │ │ │ │
│ │ 200✓ │ │ 200✓ │ │ 503✗ │ │
│ │ HEALTHY│ │ HEALTHY│ │UNHEALTHY│ │
│ └────────┘ └────────┘ └────────┘ │
│ ↑ ↑ ✗ │
│ │ │ │ │
│ يستقبل يستقبل لا يستقبل │
│ حركة حركة حركة │
│ │
└─────────────────────────────────────────────────────────────┘
إعدادات الفحص الصحي
التكوين
┌─────────────────────────────────────────────────────────────┐
│ 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 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
دورة حياة الهدف
┌─────────────────────────────────────────────────────────────┐
│ É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
التنفيذ الموصى به
┌─────────────────────────────────────────────────────────────┐
│ 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" │
│ } │
│ } │
│ │
└─────────────────────────────────────────────────────────────┘
أمثلة على الكود
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 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 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
أنواع الفحوصات الصحية
| النوع | ما الذي يتحقق منه | متى يستخدم |
|---|---|---|
| Shallow | التطبيق يستجيب (200 OK) | الحد الأدنى الضروري |
| Deep | التطبيق + التبعيات (DB، cache) | الإنتاج |
| Liveness | التطبيق حي | Kubernetes |
| Readiness | التطبيق يمكنه استقبال الحركة | Kubernetes |
تكوين 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 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 ... │
│ │
└─────────────────────────────────────────────────────────────┘
ملخص
| المعلمة | القيمة الموصى بها | التأثير |
|---|---|---|
| Interval | 30s | تكرار التحقق |
| Timeout | 5s | الحد الأقصى لوقت الاستجابة |
| Healthy Threshold | 2 | عودة سريعة للخدمة |
| Unhealthy Threshold | 3 | تجنب الإيجابيات الكاذبة |
| Path | /health | نقطة نهاية مخصصة |
القسم التالي: مختبر بنية HA