Aller au contenu

Chaos Backend

Les 7 anomalies backend dégradent le container perfshop-app (Spring Boot). Toutes sont contrôlées par des sliders 0–100% depuis l'onglet 🔧 Chaos Backend du chaos-admin.


1. CPU Burn 🔥

Implémentation : CpuChaosScheduler.java

Boucle SHA-256 exécutée toutes les 100ms sur un pool de threads. Formule : iterations = intensity × 3200, exécutée en parallèle sur ratio threads simultanés.

@Scheduled(fixedRate = 100)
public void executeCpuChaos() {
    int iterations = intensity * 3_200; // 100% → 320 000 iter/100ms
    int ratio = chaosService.getCpuRatio();  // 1 à 5 threads parallèles
    for (int t = 0; t < ratio; t++) {
        executorService.submit(() -> {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            for (int i = 0; i < iterations; i++) {
                wasteResult = digest.digest(salted);
            }
        });
    }
}

Ratio multiplier (×1 à ×5)

Ratio Threads parallèles Usage recommandé
×1 1 NAS / machine lente (défaut)
×2 2 PC bureau entrée de gamme
×3 3 PC bureau puissant
×4 4 Workstation
×5 5 Serveur multi-cœurs 🔥

Endpoint :

POST /api/admin/chaos/cpu
{ "intensity": 80, "ratio": 3 }

Métriques impactées : - docker_container_cpu_percent{container="perfshop-app"} → monte proportionnellement à intensity × ratio - http_server_requests_seconds p99 → augmente si CPU saturé


2. Memory Leak 💾

Implémentation : MemoryLeakSimulator.java

Accumulation d'objets en mémoire jamais libérés, provoquant une montée continue du heap JVM et des cycles GC de plus en plus fréquents.

Auto-nettoyage : quand l'intensité repasse à 0, clearLeakedMemory() est appelé automatiquement — la mémoire est libérée sans redémarrage du container.

Métriques impactées : - jvm_memory_used_bytes{area="heap"} → montée continue - jvm_gc_pause_seconds_sum → augmente - jvm_gc_pause_seconds_count → fréquence GC augmente


3. Thread Pool Chaos 🧵

Implémentation : ChaosInterceptor.java

Thread.sleep() bloquants injectés dans chaque requête HTTP via l'intercepteur Spring. Les threads Tomcat restent occupés sans traiter de nouvelles requêtes → saturation progressive.

Formule progressive :

Intensité Délai injecté
1–24% intensity × 20ms (ex: 20% → 400ms)
25–49% intensity × 30ms (ex: 40% → 1200ms)
50–74% 1500ms fixe
75–99% 3000ms fixe
100% 5000ms fixe

Métriques impactées : - tomcat_threads_busy_threads → monte vers le max (200) - jvm_threads_states_threads{state="timed-waiting"} → augmente - http_server_requests_seconds → latence explose


4. DB Pool Chaos 🗄️

Implémentation : DbPoolChaosScheduler.java

Acquisition de connexions HikariCP sans les libérer → pool épuisé, les requêtes suivantes attendent en file.

Thread-safety : heldConnections est une Collections.synchronizedList() — pas de race condition si plusieurs threads tentent d'acquérir simultanément.

Métriques impactées : - hikaricp_connections_active → monte vers le max (20) - hikaricp_connections_pending → files d'attente - hikaricp_connections_acquire_seconds → temps d'acquisition explose


5. Slow Query 🐌

Implémentation : ChaosInterceptor.java + ProductService.java

Injection de délais applicatifs simulant des requêtes SQL lentes. La formule est unifiée entre ChaosInterceptor et ProductService pour éviter des comportements incohérents selon l'endpoint appelé.

Formule unifiée :

Intensité Délai injecté
1–24% intensity × 15ms
25–49% intensity × 25ms (ex: 40% → 1000ms)
50–74% 2000ms fixe
75–99% 4000ms fixe
100% 6000ms fixe

Couverture endpoints : - /api/products — délai dans ProductService (toutes méthodes : getAllProducts, getProductById, searchProducts, getAllCategories) - /api/orders, /api/auth, /api/cart — délai dans ChaosInterceptor (pas de cumul avec ProductService)

Métriques impactées : - http_server_requests_seconds_bucket{uri="/api/products"} p99 → explose - hikaricp_connections_acquire_seconds → connexions tenues longtemps


6. Deadlock 🔒

Implémentation : OrderService.java + OrderController.java

Simule un conflit de transaction (deadlock BDD) avec attente du verrou puis rollback aléatoire.

Formule progressive :

Intensité Déclenchement Attente max Probabilité d'échec
1–49% intensity% des requêtes 1000ms intensity/2%
50–74% intensity% des requêtes 2000ms intensity/2%
75–99% intensity% des requêtes 3000ms intensity/2%
100% Toujours 5000ms 50%

Couverture endpoints : - POST /api/orders → chaos déclenché avant création de la commande - GET /api/orders → chaos déclenché sur la liste des commandes (visible sans checkout, utile sous charge JMeter)

En cas d'échec : RuntimeException("Database deadlock detected — transaction rolled back") → HTTP 500.

Métriques impactées : - jvm_threads_states_threads{state="blocked"} → monte - http_server_requests_seconds_count{status="5xx"} → erreurs 500


7. Network Timeout 🌍

Implémentation : ChaosInterceptor.java + OrderService.processPaymentPublic()

Deux niveaux de délai simulant une dépendance réseau externe dégradée :

  1. Intercepteur HTTP — délai sur l'ensemble de la requête (tous endpoints du parcours)
  2. Service de paiement — délai supplémentaire simulant un timeout du prestataire de paiement (uniquement sur POST /api/orders)

Formule intercepteur (plafonnée à 6s) :

Intensité Délai Probabilité de déclenchement
1–49% intensity × 20ms intensity%
50–74% 1500ms intensity%
75–99% 3000ms intensity%
100% 6000ms 100%

Formule paiement (plafonnée à 4s) :

Intensité Délai paiement
50–74% 1500ms
75–99% 2500ms
100% 4000ms

Total max à 100% : 6s (intercepteur) + 4s (paiement) = ~10s — sous le timeout client usuel de 15s.

503 aléatoire : à partir de 75% d'intensité, 20% de chance de recevoir un 503.

Endpoints couverts : - /api/orders, /api/auth, /api/products, /api/cart

Métriques impactées : - http_server_requests_seconds toutes percentiles → augmentent uniformément - http_server_requests_seconds_count{status="5xx"} → 503 occasionnels à haute intensité