Aller au contenu

Vue d'ensemble

PerfShop est une plateforme pédagogique de chaos engineering : une boutique e-commerce volontairement instrumentée pour qu'un formateur puisse y injecter à chaud des anomalies de performance, de sécurité, métier, fonctionnelles ou de scripting, et que des étudiants observent les conséquences en temps réel à travers une stack d'observabilité complète.

Cette page donne la vision niveau 1 : qui interagit avec quoi, et quels sont les grands blocs fonctionnels. Les pages suivantes (stack, deployment, database, auth, multi-session, docker, network) descendent progressivement dans le détail.

Source de vérité

Toute cette section reflète l'état réel des fichiers Docker Compose de déploiement (docker-compose.desktop.yml pour Docker Desktop, docker-compose.build.yml pour Linux/VPS), des entités JPA du backend, et des fichiers de configuration des services d'observabilité et de QA. Aucune information n'a été inventée ; chaque détail est vérifiable dans le code source.

Acteurs et systèmes

C4Context
  title PerfShop — Contexte fonctionnel (C4 niveau 1)

  Person(eleve, "Étudiant", "Suit un parcours pédagogique<br/>(BAC1 à BAC5)")
  Person(formateur, "Formateur", "Active les chaos, suit les sessions,<br/>analyse les métriques")
  Person(client, "Client final<br/>(rôle joué)", "Navigue sur la boutique,<br/>passe une commande")

  System_Boundary(perfshop, "PerfShop") {
    System(shop, "Boutique e-commerce", "Spring Boot + React<br/>Catalogue, panier, checkout")
    System(chaos, "Moteur Chaos", "6 familles d'anomalies<br/>injectables à chaud")
    System(obs, "Observabilité", "Prometheus, Grafana,<br/>Loki, Tempo, Pyroscope,<br/>OpenSearch")
    System(qa, "Stack QA", "Squash TM, Selenium,<br/>JMeter, Forgejo,<br/>Test Runner polyglotte")
    System(ped, "Moteur pédagogique", "Énigmes, sessions,<br/>code agent, étoiles")
  }

  Rel(client, shop, "Achète", "HTTPS")
  Rel(eleve, ped, "Joue les énigmes", "HTTPS")
  Rel(eleve, obs, "Observe les métriques", "Grafana Élèves")
  Rel(formateur, chaos, "Active / désactive", "X-Admin-Token")
  Rel(formateur, obs, "Analyse", "Grafana Formateurs")
  Rel(formateur, qa, "Lance les tests", "Web UI")

  Rel(chaos, shop, "Injecte des anomalies", "Interceptor Spring")
  Rel(shop, obs, "Métriques + traces + logs", "Prometheus / OTLP / Docker")
  Rel(qa, shop, "Tests Selenium / JMeter", "HTTP")

Trois usages se croisent dans la même plateforme :

  • Le client final est un personnage joué par l'étudiant ou par un script de test : il navigue dans la boutique e-commerce, ajoute des produits au panier, passe commande. C'est le « rôle utilisateur normal ».
  • L'étudiant suit un parcours pédagogique structuré en 5 niveaux (BAC1 → BAC5). Il a sa propre page (chaos student page) où il découvre les énigmes, valide les étapes et observe les conséquences des chaos activés par le formateur. Il accède aux dashboards Grafana « Élèves » sans authentification.
  • Le formateur pilote toute la séance via l'interface chaos-admin et le portail admin. Il active les anomalies, gère les comptes, ouvre/ferme l'accès à la page étudiant, analyse les sessions et accède aux dashboards Grafana « Formateurs » réservés.

Grands blocs fonctionnels

flowchart TB
  subgraph CORE["Cœur applicatif"]
    direction LR
    FE["perfshop-frontend<br/>React 18 + Vite"]
    BE["perfshop-app<br/>Spring Boot 3.2 + Java 21"]
    DB[("perfshop-db<br/>MySQL 8")]
    FE -->|REST + cookies session| BE
    BE --> DB
  end

  subgraph CHAOS["Pilotage Chaos"]
    direction LR
    CADM["perfshop-chaos-admin<br/>nginx statique"]
    ADM["perfshop-admin<br/>nginx statique"]
    MON["perfshop-monitoring<br/>Node + Express"]
  end

  subgraph OBS["Observabilité"]
    direction LR
    PROM["Prometheus"]
    GRAF["Grafana"]
    LOKI["Loki + Promtail"]
    TEMPO["Tempo"]
    PYRO["Pyroscope"]
    OS["OpenSearch + Vector"]
  end

  subgraph QA["Stack QA"]
    direction LR
    SQ["Squash TM + Orchestrator"]
    SEL["Selenium Grid"]
    TR["Test Runner<br/>RF + pytest"]
    JM["JMeter + JMeter UI"]
    FG["Forgejo"]
    SU["Scripts UI"]
  end

  CADM -->|X-Admin-Token| BE
  ADM -->|X-Admin-Token| BE
  MON -->|polling 2s| BE

  BE -->|"/actuator/prometheus<br/>scrape 5s"| PROM
  BE -->|OTLP gRPC 4317| TEMPO
  BE -->|JFR push| PYRO
  PROM --> GRAF
  LOKI --> GRAF
  TEMPO --> GRAF
  PYRO --> GRAF
  OS -->|Dashboards| GRAF

  SQ --> SEL
  SQ --> TR
  TR -->|HTTP| FE
  JM -->|HTTP| BE
  SU --> FG
  SU --> TR

Cinq blocs cohabitent sur le même réseau Docker perfshop-network. Chaque bloc est documenté dans sa propre page :

Bloc Page de référence Nombre de services
Cœur applicatif Stack technique, Schéma de données 3
Pilotage Chaos Authentification 3
Observabilité Vue d'ensemble 9
Stack QA Vue d'ensemble 8
Outils transverses Docker Compose 9

Flux de données principaux

PerfShop manipule quatre flux de télémétrie parallèles, chacun avec son protocole et son stockage propre.

flowchart LR
  APP["perfshop-app<br/>Spring Boot"]

  APP -->|"/actuator/prometheus<br/>HTTP scrape 5s"| MET[("Prometheus<br/>retention 7j / 5GB")]
  APP -->|"OTLP gRPC<br/>:4317"| TRC[("Tempo<br/>blocks locaux")]
  APP -->|"JFR push HTTP<br/>:4040"| PRF[("Pyroscope<br/>filesystem")]
  APP -->|"stdout / stderr"| DOC{"Docker<br/>logging driver"}

  DOC --> PT["Promtail<br/>(docker SD)"] --> LOG[("Loki<br/>retention 7j")]
  DOC --> VEC["Vector<br/>(VRL transform)"] --> OS[("OpenSearch<br/>perfshop-spring*")]

  MET --> GRAF["Grafana<br/>dashboards"]
  LOG --> GRAF
  TRC --> GRAF
  PRF --> GRAF
  OS  --> OSD["OpenSearch<br/>Dashboards"]
  • Métriques : Prometheus scrape perfshop-app:9090/actuator/prometheus toutes les 5 secondes (job perfshop-backend), perfshop-monitoring:3001/metrics pour les métriques Docker (job perfshop-docker), et perfshop-jmeter:9270 pendant les tirs JMeter (job jmeter). Détails dans observability/prometheus.md.
  • Traces : l'agent Java OpenTelemetry est embarqué dans l'image perfshop-backend et exporte les spans en OTLP gRPC vers perfshop-tempo:4317. Détails dans observability/tempo.md.
  • Profiling continu : l'agent Java Pyroscope est lui aussi embarqué dans l'image et pousse en format JFR vers perfshop-pyroscope:4040. Détails dans observability/pyroscope.md.
  • Logs : ils sont collectés deux fois en parallèle. Promtail lit le socket Docker pour alimenter Loki ; Vector lit le même socket pour alimenter OpenSearch (avec un parsing VRL plus poussé qui isole les champs chaos_family, chaos_level, scenario_id). Les deux puits coexistent volontairement comme démonstration pédagogique.

Cycle de vie d'une requête

Une requête HTTP arrivant sur le backend traverse plusieurs couches avant d'atteindre le contrôleur métier.

sequenceDiagram
  autonumber
  participant N as Navigateur
  participant FE as perfshop-frontend<br/>(nginx)
  participant BE as perfshop-app<br/>(Tomcat)
  participant LI as LicenseInterceptor
  participant CI as ChaosInterceptor
  participant CT as Contrôleur
  participant DB as MySQL
  participant T as Tempo / Pyroscope

  N->>FE: GET /products
  FE->>BE: GET /api/products
  BE->>LI: handle()
  alt Licence absente
    LI-->>N: HTTP 402 Payment Required
  else Licence valide
    LI->>CI: handle()
    CI->>CI: Inject anomalies actives
    CI->>CT: ProductController.list()
    CT->>DB: SELECT (HikariCP)
    DB-->>CT: rows
    CT-->>N: 200 JSON
    BE->>T: span OTLP + sample CPU
  end

L'ordre des intercepteurs est verrouillé dans WebConfig.java :

  1. LicenseInterceptor (ordre 1) — vérifie qu'une licence valide est présente. Sans licence, toute requête vers /api/** est rejetée par un HTTP 402 Payment Required. Seuls les endpoints /actuator/** sont exclus de cette vérification.
  2. ChaosInterceptor (ordre 2) — n'est traversé que si la licence est valide. Il consulte l'état des chaos actifs et injecte les anomalies (latence artificielle, exception aléatoire, corruption de réponse, etc.) avant de laisser la requête atteindre le contrôleur.

CORS est géré séparément par CorsConfig.java qui autorise dynamiquement les origines listées dans la variable CORS_ALLOWED_ORIGINS du compose et expose explicitement les headers utilisés par le Chaos Scripting (X-Session-Token, X-Action-Token, X-CSRF-Token, X-Step-Token, X-Signature, X-Request-ID, X-Key-Hint).

Hub de jeux pédagogiques

PerfShop embarque également un hub de jeux pédagogiques débloqué en fin de parcours BAC. C'est une application web statique distincte de la boutique, construite en JavaScript moderne (modules ES, Vite 5) et fondée sur les frameworks Phaser 3.80 (jeux 2D, ex. Server Defender) et Three.js 0.160 (rendus 3D). Le hub est servi par nginx en conteneur indépendant et n'a aucune dépendance backend : tout le gameplay tourne côté navigateur. Voir le futur lot consacré aux jeux pour le détail de l'architecture interne.

Pour aller plus loin