Architecture backend guidée par les contraintes et les seuils
Principe
Commencer par le système le plus simple qui satisfait les contraintes mesurées. La scalabilité n'est pas une collection de services : c'est la capacité à conserver objectifs de latence, débit, disponibilité, cohérence et coût lorsque la charge évolue.
Séquence de décision
1. Cadrer
- Cas d'usage prioritaires et explicitement hors périmètre.
- Charge moyenne/pic : requêtes/s, écritures/s, volume stocké, croissance, taille des objets.
- SLO : disponibilité, latence p95/p99, durabilité, fraîcheur et RPO/RTO.
- Contraintes : équipe, budget, données sensibles, région, dépendances et délai.
Produire quelques calculs d'ordre de grandeur. Une hypothèse chiffrée et révisable vaut mieux qu'un composant ajouté « pour scaler ».
2. Dessiner le flux minimal
client → reverse proxy → application stateless → base principale
↘ file/worker si travail lent
↘ cache si mesure le justifie
Définir contrats, modèle de données, chemin de lecture/écriture, erreurs, idempotence et observabilité avant de multiplier les services.
3. Trouver le goulot réel
- CPU ou event loop : profiler, réduire le travail synchrone, déplacer le calcul approprié.
- Base : plans de requête/index, pooling, modèle, puis réplique ou partition seulement si nécessaire.
- Réseau/objets : compression, CDN et cache avec invalidation explicite.
- Travail long : file, retries bornés, idempotency key, dead-letter et backpressure.
- Disponibilité : health/readiness, redondance, sauvegarde restaurée en test, failover documenté.
4. Ajouter une brique avec son coût
Chaque décision d'architecture précise : problème mesuré, solution, alternative rejetée, modes de panne, données possédées, métriques, coût opérationnel, stratégie de migration et condition de retrait.
Cohérence et disponibilité
Choisir par opération, pas globalement. Paiement, identité ou stock peuvent demander une cohérence forte ; feed, analytics ou cache peuvent accepter un retard borné. Documenter ce que voit l'utilisateur pendant une partition ou un retry.
Monolithe modulaire d'abord
Pour une petite équipe, un monolithe modulaire avec frontières métier, API interne claire, base maîtrisée et déploiement reproductible est souvent le meilleur défaut. Extraire un service seulement lorsqu'une frontière a un besoin indépendant de déploiement, charge, sécurité ou propriété d'équipe.
Revue obligatoire
- Diagramme de contexte et séquence du chemin critique.
- Failure modes : timeout, dépendance indisponible, message doublé, écriture partielle, reprise après crash.
- Load test proportionné aux hypothèses.
- Dashboards reliés aux SLO et alerte actionnable.
- Runbook de déploiement, rollback, sauvegarde/restauration et incident.
Références
- [[KNOW-REF-014]] — System Design Primer et exercices
- Martin Fowler — Patterns of Distributed Systems
- Microsoft — Cloud Design Patterns
- microservices.io — catalogue de patterns et compromis microservices
- [[KNOW-PAT-228]] — contrats REST
- [[KNOW-PAT-229]] — cache et invalidation