Une application SaaS commence à perdre des requêtes à 14 h tous les jours. Les métriques CloudWatch d’ALB montrent les cibles qui passent de malsaine à saine en succession rapide. L’équipe vérifie les journaux applicatifs et ne trouve rien — l’app tourne, le processus est en vie, les requêtes sont servies. Le chemin de vérification de santé est /, le défaut. / retourne le HTML d’index du SPA en 5 ms parce que la requête ne touche jamais la base de données ni le cache. Le vrai problème est que le pool de connexions à la base de données de l’application est épuisé ; les vraies requêtes utilisateur expirent, mais la vérification de santé passe parce qu’elle n’exerce pas la dépendance qui échoue. ALB voit des cibles saines, route le trafic vers elles, les requêtes échouent, les utilisateurs voient des erreurs. La correction est de faire en sorte que la vérification de santé exerce réellement les dépendances dont l’application a besoin — et de régler l’intervalle et le seuil pour qu’une cible lente soit retirée de la rotation avant qu’elle ne cascade, mais pas si agressivement qu’un bref incident fasse vaciller toute la flotte.
Ce qui se passe
Les vérifications de santé ALB sont des requêtes HTTP indépendantes qu’ALB envoie à chaque cible selon un calendrier. La cible est « saine » ou « malsaine » selon que la réponse correspond aux critères de succès configurés. ALB ne route le trafic que vers des cibles saines.
Les paramètres qui comptent :
-
HealthCheckPath— Le chemin URL que la vérification atteint. Défaut est/. Pour la plupart des applications modernes,/retourne le bundle SPA depuis un actif en cache CDN ou un fichier d’index statique — cela ne vous dit rien sur la capacité de l’application à servir des requêtes. -
HealthCheckIntervalSeconds— À quelle fréquence ALB vérifie chaque cible. Défaut est 30 secondes. Plage de 5 à 300. -
HealthCheckTimeoutSeconds— Combien de temps ALB attend une réponse. Défaut est 5 secondes. Doit être inférieur à l’intervalle. -
HealthyThresholdCount— Combien de succès consécutifs font basculer une cible de malsaine à saine. Défaut est 5. -
UnhealthyThresholdCount— Combien d’échecs consécutifs font basculer une cible de saine à malsaine. Défaut est 2. -
Matcher— Quels codes de statut HTTP comptent comme succès. Défaut pour les cibles HTTP est 200. Peut être une plage comme200-299ou une liste comme200,201,302. -
Période de grâce de vérification de santé (attribut de target group
health_check.grace_period_seconds) — Sur une cible nouvellement enregistrée, combien de temps ALB attend avant que sa première vérification de santé ne compte. Défaut est 30 secondes. Pour une cible qui prend 90 secondes à se réchauffer (JVM, gros pull d’image, résolution de dépendances), le défaut signifie que la cible est tuée avant même de servir une requête.
Les deux chemins distincts de vérification de santé que toute application devrait exposer :
-
Chemin de vivacité (
/healthz). Retourne 200 si le processus est en marche et le runtime est répondant. Ne touche pas à la base de données, au cache, ni aux services externes. Bon marché, rapide, n’échoue jamais pour une raison amont. Utilisé par l’orchestrateur (ASG, ECS) pour décider si le processus doit être tué et redémarré. -
Chemin de préparation (
/ready). Retourne 200 si l’application peut réellement servir de vraies requêtes. Touche la base de données avec unSELECT 1, ping le cache, confirme que le client API externe est configuré. Plus lent, plus coûteux, peut échouer pour des raisons amont. Utilisé par le load balancer pour décider si la cible doit recevoir du trafic.
ALB devrait faire la vérification de santé sur le chemin de préparation. Si la base de données est tombée et que /ready retourne 503, ALB retire la cible de la rotation et arrête de lui envoyer du trafic utilisateur. La cible reste en vie (le processus va bien) ; quand la base de données récupère, /ready recommence à retourner 200 et ALB remet la cible dans la rotation. L’utilisateur voit un bref accroc pendant la panne de base de données mais pas d’erreurs en cascade.
Pointer ALB sur /healthz à la place est le mauvais choix pour SaaS. Le processus est en marche ; l’application ne peut pas servir de vraies requêtes ; ALB envoie quand même du trafic ; les utilisateurs reçoivent des erreurs.
Comment vérifier
Inspecter la configuration courante de vérification de santé sur un target group :
aws elbv2 describe-target-groups --target-group-arns "$TG_ARN" \
--query 'TargetGroups[].{
Path: HealthCheckPath,
Interval: HealthCheckIntervalSeconds,
Timeout: HealthCheckTimeoutSeconds,
Healthy: HealthyThresholdCount,
Unhealthy: UnhealthyThresholdCount,
Matcher: Matcher.HttpCode
}'
Vérifier l’état de santé courant de chaque cible :
aws elbv2 describe-target-health --target-group-arn "$TG_ARN" \
--query 'TargetHealthDescriptions[].{
Target: Target.Id,
Port: Target.Port,
State: TargetHealth.State,
Reason: TargetHealth.Reason,
Description: TargetHealth.Description
}'
Le champ Reason vous dit pourquoi une cible est malsaine. Target.FailedHealthChecks signifie que le chemin a retourné un statut non-succès. Elb.RegistrationInProgress signifie que la cible est encore dans la période de grâce. Target.Timeout signifie que la réponse n’est pas arrivée dans HealthCheckTimeoutSeconds.
Régler le timeout pour une app SaaS qui fait un aller-retour base de données dans la vérification de préparation :
- Un
/readyqui frappe la base de données répond typiquement en 50-200 ms quand sain. RéglerHealthCheckTimeoutSeconds=2est raisonnable — assez long pour une réponse saine, assez court pour attraper une lente. - L’intervalle de 10 secondes signifie qu’ALB voit une cible malsaine dans les 10-30 secondes.
UnhealthyThresholdCount=2signifie que deux échecs consécutifs retirent la cible. Avec un intervalle de 10 secondes, ça donne 20 secondes entre « premier échec » et « hors rotation ».HealthyThresholdCount=2signifie que deux succès consécutifs la remettent. Récupération plus rapide.
Une configuration SaaS typique :
aws elbv2 modify-target-group \
--target-group-arn "$TG_ARN" \
--health-check-path /ready \
--health-check-interval-seconds 10 \
--health-check-timeout-seconds 2 \
--healthy-threshold-count 2 \
--unhealthy-threshold-count 2 \
--matcher HttpCode=200
Pour la période de grâce sur une cible qui prend du temps à se réchauffer :
aws elbv2 modify-target-group-attributes \
--target-group-arn "$TG_ARN" \
--attributes Key=health_check.grace_period_seconds,Value=120
Pour une app Java avec réchauffe JVM, 120 secondes est raisonnable. Pour une app Node, 30 secondes suffit largement. Pour un target group adossé à Lambda, la période de grâce est sans objet — le démarrage à froid de Lambda est le réchauffe.
Confirmer que le chemin de préparation exerce vraiment les dépendances. Le moyen le moins cher est de vérifier côté application que /ready appelle la base de données :
# gestionnaire Flask minimal
@app.route('/ready')
def ready():
try:
db.session.execute('SELECT 1')
cache.get('healthcheck') # ping du cache
return 'OK', 200
except Exception as e:
return str(e), 503
Côté opérations, le test consiste à casser la dépendance exprès. Arrêtez la base de données dans un environnement de mise en scène. La cible devrait devenir malsaine en (intervalle × seuil malsain) secondes. L’application devrait continuer à tourner. Redémarrez la base de données. La cible devrait récupérer en (intervalle × seuil sain) secondes.
La correction
Le runbook pour régler les vérifications de santé sur un target group existant :
-
Auditer le chemin de vérification de santé. Si c’est
/, changez-le. Le chemin doit être une route que possède l’application, pas un actif statique. -
Ajouter ou corriger l’endpoint
/readydans l’application. L’endpoint exerce les dépendances que l’application utilise pour les vraies requêtes. Ping base de données, ping cache, statut du client API en aval. -
Définir le chemin sur
/readyet le matcher sur 200 uniquement. Ne correspondez pas à une plage ; un 200 dit « je peux servir le trafic », un 503 dit « je ne peux pas ». Toute autre chose est une erreur de codage à faire remonter, pas à absorber. -
Régler l’intervalle et le seuil pour la charge de travail. Détection rapide (petit intervalle, seuil bas) pour la SaaS à fort trafic où une minute de cibles mortes signifie beaucoup de requêtes échouées. Détection plus lente pour les outils internes à faible trafic où les faux positifs comptent plus que la vitesse absolue.
-
Définir la période de grâce au temps de réchauffe réel. Chronométrez l’application du démarrage à la première requête réussie dans un environnement représentatif. Définissez la période de grâce à ce nombre plus 30 secondes de marge.
-
Câbler une alarme CloudWatch sur
UnHealthyHostCount. Se déclenche quand n’importe quel hôte est malsain pendant plus d’une minute. L’alarme vous dit quel target group, vous vérifiez leTargetHealth.Reasonpour savoir pourquoi. -
Tester en cassant une dépendance en mise en scène. Vérifiez que la cible devient malsaine comme prévu, que le trafic utilisateur arrête d’atterrir dessus, et que la récupération est automatique. La première fois que vous découvrez que la vérification de santé ne se comporte pas comme prévu ne devrait pas être en production.
Trois règles que nous tenons :
Vivacité et préparation sont des endpoints différents. L’orchestrateur veut savoir « est-ce que le processus est en marche ». Le load balancer veut savoir « est-ce que le processus peut servir le trafic ». Les confondre signifie que soit l’orchestrateur tue des cibles qu’il ne devrait pas, soit le load balancer route vers des cibles qui ne peuvent pas servir.
Plafonner le coût de la vérification de préparation. Un /ready qui exécute un test d’intégration complet toutes les 10 secondes est sa propre charge sur la base de données. Le chemin devrait faire les requêtes les moins chères qui prouvent que la dépendance est joignable — SELECT 1 suffit.
Le défaut est faux. La vérification de santé par défaut d’ALB (chemin /, intervalle 30 s, seuil 5, matcher 200) est calibrée pour « site statique sans dépendances ». Pour une SaaS, les défauts prendront 2,5 minutes pour détecter une cible cassée et pourraient ne jamais détecter une défaillance de dépendance.
Pour plus de détails sur le contexte des règles ALB où les vérifications de santé vivent, voir Règles de listener ALB — routage par hôte et par chemin. Pour les interactions entre sessions persistantes et vérifications de santé (une cible malsaine évince ses clients persistants), voir Les sessions persistantes sont un signal.
Stack Harbor conçoit les topologies ALB + NLB et le modèle d’opération autour dans le cadre de l’onboarding Gestion AWS et des Environnements infogérés en continu. Si votre flotte vacille chaque après-midi et que les journaux applicatifs sont silencieux, commencez par une consultation d’infrastructure.