Un goulot d'étranglement se manifeste rarement là où on l'attend. Sur une mission dans le secteur assurantiel, le problème de performance d'un processus de souscription était imputé aux serveurs applicatifs — l'analyse a révélé une requête SQL non indexée consommant 85% du temps de transaction. Voici la méthode que j'applique systématiquement.
Étape 1 : Définir les métriques de référence
Avant le premier test, je définis avec les équipes les indicateurs cibles :
- Temps de réponse : P50, P90, P95, P99 (le P99 révèle les comportements extrêmes)
- Throughput (TPS — transactions par seconde)
- Taux d'erreur HTTP (objectif < 0,1%)
- SLA techniques : CPU < 70%, RAM < 80%, temps de réponse BDD < 100ms
Ces métriques deviennent les critères d'acceptation du test et les seuils des alertes Dynatrace.
Étape 2 : Analyse top-down
Je commence toujours par les métriques agrégées (temps de réponse global) avant de descendre dans le détail :
- Niveau réseau : latence réseau, DNS lookup, temps de connexion TLS
- Niveau serveur web/load balancer : saturation des connexions, temps de traitement nginx/HAProxy
- Niveau applicatif : profiling CPU/mémoire JVM, garbage collection, pool de threads
- Niveau base de données : slow queries, index manquants, deadlocks, pool de connexions saturé
Dynatrace PurePath automatise cette analyse en décomposant le temps de réponse par couche. Sans APM, j'utilise les logs applicatifs combinés à htop, iostat et vmstat sur les serveurs.
Étape 3 : Profiling BDD — le suspect numéro 1
Dans 60% des cas de débutants, le bottleneck se trouve en base de données. Les patterns récurrents :
- N+1 query : une liste de 100 items génère 101 requêtes SQL au lieu d'une seule avec JOIN
- Requêtes sans index : un
SELECT * FROM transactions WHERE user_id = ?sans index suruser_idprovoque un full table scan dévastateur sous charge - Contention de verrous : transactions longues bloquant l'accès concurrent sur les tables critiques
Outils : EXPLAIN ANALYZE (PostgreSQL), pg_stat_statements, Dynatrace Database statements, ou simplement les slow query logs MySQL.
Étape 4 : Identifier le point de saturation
Je fais varier la charge progressivement (rampe de 10 à 500 utilisateurs) et j'observe où le système commence à dégrader. La loi de Little (N = λ × W) permet de calculer le throughput maximal théorique. En pratique, la saturation survient souvent à 60-70% de la capacité théorique à cause de la contention.
Étape 5 : Documenter et valider le correctif
Une fois le correctif appliqué (ajout d'index, optimisation de requête, augmentation du pool de connexions), je relance le test dans les exactes mêmes conditions que le test initial et je compare les résultats. La traçabilité est essentielle : même scénario, même population, même durée, même charge.
Cas réel : réduction de 70% du temps de réponse
Sur un projet de refonte d'un moteur de règles métier en secteur assurance : temps de réponse initial à 4,2 secondes au P95 sous 200 utilisateurs. Après analyse PurePath Dynatrace : 3,8 secondes passées dans une procédure stockée Oracle exécutée 8 fois par transaction. Après refactoring (cache applicatif + réécriture en requête batch) : 1,1 seconde au P95 — réduction de 74%.
Sources & références
- Martin Fowler — "Patterns of Enterprise Application Architecture" (2002) — chapitre Database Patterns
- Brendan Gregg — "Systems Performance: Enterprise and the Cloud" (2020, 2e éd.), Addison-Wesley
- AWS Well-Architected Framework — Performance Efficiency Pillar : docs.aws.amazon.com/wellarchitected
- PostgreSQL Documentation — Using EXPLAIN : postgresql.org/docs/current/using-explain.html