MAISON CODE .
/ Tech · Performance · QA · Scaling · Backend

Tests de charge : casser votre site volontairement

Votre site fonctionne avec 1 utilisateur. Est-ce que ça marche avec 10 000 ? Comment utiliser k6 pour simuler des pics de trafic massifs et identifier les goulots d'étranglement avant le Black Friday.

AB
Alex B.
Tests de charge : casser votre site volontairement

Le modèle « Succès-catastrophe »

Le moment le plus dangereux pour une startup n’est pas l’échec. C’est un Succès. Imaginez ce scénario : Vous lancez une nouvelle campagne marketing. Ou vous êtes présenté sur TechCrunch. Ou un influenceur avec 5 millions de followers publie des publications sur votre produit. Le trafic augmente de 100 fois du jour au lendemain. Vous êtes prêt à gagner des millions. Et puis… le site se charge en blanc. 504 Délai d’expiration de la passerelle. Service 503 indisponible. Le processeur de votre base de données atteint 100 %. Votre pool de connexions est épuisé. Les utilisateurs actualisent la page, ajoutant plus de charge. Le système entre dans une spirale mortelle. Vous paniquez. Vous essayez de mettre à niveau la base de données sur AWS, mais l’application prend 30 minutes. Au moment où le site est rétabli, le trafic a disparu. Les utilisateurs sont en colère. La réputation est endommagée.

Il s’agit d’un désastre à succès. Vous avez réussi en marketing, mais avez échoué en ingénierie. Load Testing force ce scénario à se produire dans un environnement contrôlé, des jours ou des semaines avant l’événement réel. Nous simulons le crash. Nous trouvons le goulot d’étranglement. Nous le réparons. Nous répétons.

Pourquoi Maison Code en parle

Chez Maison Code, nous sommes spécialisés dans le e-commerce « Haute Pression ». Nos clients ne sont pas des blogs typiques. Ce sont des marques qui lancent des baskets en édition limitée à 10h00. Ils passent de 0 visiteur à 50 000 visiteurs en 3 secondes. Nous avons appris par expérience que L’évolutivité n’est pas magique ; ce sont des mathématiques. Si vous n’avez pas testé votre système à 10 fois votre charge attendue, vous ne disposez pas d’un système robuste ; vous avez une prière. Nous écrivons à ce sujet parce que nous voulons épargner aux fondateurs le chagrin de voir leur « grand moment » se transformer en une panne publique.

L’outil : k6 (Grafana)

Pendant longtemps, la norme était JMeter. C’était puissant mais pénible (interface graphique basée sur XML). Puis Locust (Python) est devenu populaire. Mais aujourd’hui, la norme industrielle est k6. Pourquoi k6 ?

  1. JavaScript : les tests sont écrits en JS/TS. Les développeurs sont à l’aise avec cela.
  2. Performances : Le moteur est écrit en Go. Un ordinateur portable peut simuler 30 000 utilisateurs simultanés.
  3. CI/CD : il s’exécute facilement dans un pipeline GitHub Actions.
  4. Metrics : il s’intègre nativement à Grafana/InfluxDB pour une belle visualisation en temps réel.

Implémentation : écriture d’un script k6

Examinons un script de test de charge robuste.

importer http depuis 'k6/http' ;
importer { dormir, vérifier } depuis 'k6' ;

// Configuration : Le profil de charge
exporter les options const = {
  étapes : [
    { durée : '30 s', cible : 20 }, // Rampe jusqu'à 20 utilisateurs (échauffement)
    { durée : '1 m', cible : 50 }, // Rampe jusqu'à 50 utilisateurs (charge)
    { durée : '2 min', cible : 50 }, // Rester à 50 utilisateurs (Sustain)
    { durée : '30 s', cible : 100 }, // Pic à 100 utilisateurs (Stress)
    { durée : '30 s', cible : 0 }, // Rampe de ralentissement (refroidissement)
  ],
  seuils : {
    // Conditions d'échec
    http_req_failed : ['rate<0.01'], // Le taux d'erreur doit être < 1 %
    http_req_duration : ['p95<500'], // 95 % des requêtes doivent être < 500 ms
  },
} ;

exporter la fonction par défaut () {
  const BASE_URL = 'https://staging.maisoncode.paris';
  
  // 1. Visitez la page d'accueil
  const resHome = http.get(BASE_URL);
  check(resHome, { 
    'Statut d'accueil 200' : (r) => r.status === 200,
    'Retour rapide' : (r) => r.timings.duration < 200, 
  });
  
  dormir(1); // L'utilisateur pense...

  // 2. Recherche de produit (CPU intensif)
  const resSearch = http.get(`${BASE_URL}/api/search?q=shirt`);
  vérifier (resSearch, { 
    'Statut de recherche 200' : (r) => r.status === 200 
  });

  dormir(2);
}

Les 4 types de tests de performances

Comprenez la différence, ou vous testerez la mauvaise chose.

  1. Test de fumée :

    • Objectif : garantir que le système gère une charge minimale.
    • Charge : 1 à 5 utilisateurs virtuels (VU).
    • Quand : après chaque déploiement. « Avons-nous complètement cassé le serveur ? »
  2. Test de charge :

    • Objectif : Vérifiez que le système gère le trafic attendu.
    • Charge : Le trafic moyen de votre site de production (ex. 50 VU).
    • Quand : avant les versions mineures.
  3. Test de résistance :

    • Objectif : trouvez le point de rupture.
    • Charge : augmentez indéfiniment jusqu’à ce que le système tombe en panne.
    • Résultat : “Nous pouvons gérer 2 500 utilisateurs. À 2 501, la base de données plante.”
    • Quand : Avant des changements architecturaux majeurs.
  4. Test de trempage :

    • Objectif : trouver des fuites de mémoire.
    • Charge : charge modérée (capacité de 80 %) pendant 24 heures.
    • Résultat : “Ah, l’utilisation de la mémoire augmente de 1 % toutes les heures. Nous avons une fuite.”

Identifier les goulots d’étranglement

Vous avez trouvé le point de rupture. Maintenant, demandez Pourquoi ? Le « Pourquoi » est rarement le code lui-même. Il s’agit généralement de l’infrastructure.

  1. La base de données (le suspect habituel) :

    • Épuisement de la connexion : “FATAL : les emplacements de connexion restants sont réservés aux rôles de superutilisateur sans réplication”.
      • Correction : regroupement de connexions (PgBouncer).
    • Saturation du processeur : requêtes complexes effectuant des analyses de table complètes.
      • Correction : Indexation. Lisez les répliques. Utilisez Redis pour mettre en cache les requêtes courantes.
  2. Ponts (API) :

    • Votre site est rapide, mais vous appelez l’API Shipping pour calculer les tarifs.
    • L’API d’expédition expire sous charge.
    • Vos demandes sont mises en file d’attente en attendant l’API d’expédition.
    • Votre serveur manque de RAM.
    • Correction : délais d’attente. Disjoncteurs.
  3. La boucle d’événements (Node.js) :

    • Le nœud est monothread. Si vous effectuez des calculs CPU lourds (chiffrement, redimensionnement d’image) sur le thread principal, vous bloquez tous les utilisateurs.
    • Correction : déchargement vers des threads de travail ou des fonctions sans serveur.

La sémantique des centiles (p95, p99)

Ne jugez jamais les performances par la Moyenne. Les moyennes cachent des mensonges.

  • Utilisateur A : 100 ms
  • Utilisateur B : 100 ms
  • Utilisateur C : 10 000 ms (10 secondes)
  • Moyenne : ~3,4 s. (Ça a l’air bien).
  • p99 : 10 s. (Terrifiant).

p95 (95e centile) signifie : « Ignorez les 5 % de valeurs aberrantes les plus lentes. Quelle est la vitesse pour tous les autres ? » p99 (99e centile) signifie : “L’expérience des 1 % de requêtes les plus lentes.”

Pourquoi p99 est important : En e-commerce, les « requêtes les plus lentes » sont souvent les utilisateurs ayant les plus gros paniers. Utilisateur avec 1 élément -> Requête rapide. Utilisateur avec 50 éléments -> Requête lente. L’utilisateur p99 est votre Client à forte valeur ajoutée. Si vous ignorez p99, vous optimisez pour les lèche-vitrines et ignorez les baleines.

Des tests en production ?

DANGER. Exécuter un stress test sur la production est risqué.

  1. Vous avez foiré Analytics : Google Analytics affichera 10 000 visites de « bot », ruinant ainsi vos données marketing.
  2. Vous déclenchez des coûts : Si vous utilisez Serverless/Vercel, vous paierez pour les 10 millions de requêtes que vous venez de spammer.
  3. Alertes de fraude : Stripe pourrait vous bannir pour des modèles d’attaque de type “Test de carte”.

La règle d’or : utilisez un environnement de transfert de parité des données. La mise en scène doit être identique à Prod (même taille d’instance AWS, même taille de base de données). Si Staging est un petit t2.micro et que Prod est un énorme m5.large, les résultats de vos tests n’ont aucun sens.

14. Ingénierie du chaos (casser des choses volontairement)

Débranchez le câble de la base de données. Ce qui se produit? Le site plante-t-il ? Ou affiche-t-il une version en cache ? Nous utilisons des scripts Chaos Mesh ou génériques Pumba pour tuer les conteneurs de manière aléatoire pendant le test de charge. Si une réplique meurt, l’équilibreur de charge devrait instantanément être redirigé. Si le cache Redis meurt, la base de données devrait prendre la charge (ou prendre feu). Le savoir avant 9 heures du matin le jour du lancement n’a pas de prix.

15. Tests de charge basés sur le navigateur (navigateur K6)

Les tests de protocole (HTTP) ne restituent pas JavaScript. Ils ne détectent pas les « Erreurs d’hydratation » ou le « React Rendering Lag ». Le navigateur K6 fait tourner de véritables instances Chrome sans tête. Il mesure le CLS (Cumulative Layout Shift) et le FID (First Input Delay) sous charge. “Le serveur est rapide (API 200 ms), mais le client est lent (exécution JS 3 s) car nous avons envoyé 5 Mo de JSON.” Seuls les tests du navigateur le révèlent.

16. Automatisation des tests de charge dans CI/CD (Actions GitHub)

N’exécutez pas k6 depuis votre ordinateur portable. Exécutez-le à chaque Pull Request. Nous ajoutons un workflow load-test.yml.

  1. Déployez la branche sur l’URL intermédiaire.
  2. Exécutez « k6 run smoke-test.js » (vérifiez 500 secondes).
  3. En cas d’échec, bloquez la fusion. Cela évite les « régressions de performances ». “Le développeur junior a ajouté une boucle de requête N+1. Le test l’a détecté car la latence est passée de 200 ms à 2 000 ms.”

17. Tests de pointe vs tests de trempage

Connaissez la différence. Tests de pointe :

  • Simule une “Sneaker Drop” ou une “annonce du Super Bowl”.
  • 0 -> 10 000 utilisateurs en 10 secondes.
  • Objectif : tester les déclencheurs d’auto-scaling (les serveurs AWS tournent-ils assez vite ?). Test de trempage :
  • Simule le “Week-end du Black Friday”.
  • Charge élevée pendant 48 heures.
  • Objectif : tester les fuites de ressources (mémoire, espace disque, descripteurs de fichiers). Vous avez besoin des deux.

18. Conclusion

La performance n’est pas un « agréable à avoir ». C’est une fonctionnalité. L’évolutivité n’est pas magique. C’est de l’ingénierie. Les tests de charge sont la discipline de validation de votre ingénierie. N’attendez pas la panne d’électricité. Cassez l’ampoule vous-même, pendant que vous en avez une de rechange dans votre poche.

Vous préparez le Black Friday ?

N’attendez pas novembre. Maison Code propose des services de « Tests de stress des infrastructures ». Nous simulons des pics de trafic multipliés par 100, identifions vos goulots d’étranglement et mettons en œuvre des politiques d’auto-scaling qui fonctionnent.



Vous vous attendez à un trafic élevé ?

Nous effectuons des tests de charge et de stress à l’aide de k6 pour valider la capacité de l’infrastructure et vérifier les politiques d’auto-scaling. Embauchez nos architectes.