Critères de choix¶
Comparer les topologies avec des critères objectifs — pas par mode, mais par contexte d'équipe et de domaine.
Tableau comparatif¶
Les quatre topologies principales couvrent 95% des cas réels. Le tableau ci-dessous les compare sur les critères qui comptent au quotidien.
| Critère | Monolithe modulaire | Microservices | Event-driven | Serverless |
|---|---|---|---|---|
| Complexité initiale | Faible | Élevée | Moyenne | Faible |
| Scalabilité | Verticale + horizontale | Indépendante par service | Haute par conception | Automatique |
| Coût ops | Faible | Élevé | Moyen | Très faible (ou élevé a fort volume) |
| Taille équipe min | 1 | 5-6 par service | 3 | 1 |
| Debugging | Direct | Complexe (tracing) | Complexe (replay) | Complexe (remote) |
| Déploiement | Simple | Complexe | Moyen | Simple |
| Réversibilité | Facile vers micro | Difficile vers monolithe | Partielle | Difficile |
| Latence inter-composants | Nulle (in-process) | Réseau (ms a s) | Asynchrone (ms a min) | Variable (cold start) |
| Cohérence des données | ACID possible | Eventual consistency | Eventual consistency | Eventual consistency |
| Courbe d'apprentissage | Faible | Élevée | Moyenne | Moyenne |
Ce tableau donne une vue d'ensemble, mais les critères n'ont pas le même poids selon le contexte. Une équipe de 3 personnes qui optimise pour le time-to-market ne lira pas ce tableau de la même façon qu'une équipe de 50 qui optimise pour l'autonomie des équipes.
Arbre de décision¶
L'arbre de décision ci-dessous est opinionné. Il favorise explicitement le monolithe modulaire comme point de départ et ne recommande les microservices que quand des signaux concrets le justifient.
flowchart TD
A["Nouveau systeme"] --> B{"Equipe < 10\npersonnes ?"}
B -->|"Oui"| C{"Domaine bien\ncompris ?"}
B -->|"Non"| D{"Besoin de scale\nindependant\npar module ?"}
C -->|"Oui"| E["Monolithe modulaire"]
C -->|"Non"| F["Monolithe modulaire\nfrontieres provisoires"]
D -->|"Oui"| G{"CI/CD mature +\nmonitoring\ndistribue ?"}
D -->|"Non"| E
G -->|"Oui"| H["Microservices"]
G -->|"Non"| I["Monolithe modulaire\nd'abord"]
E --> J{"Processus\nasynchrones\ndominants ?"}
J -->|"Oui"| K["Monolithe +\nevent bus interne"]
J -->|"Non"| L["Monolithe modulaire\nsynchrone"]
H --> M{"Fonctions\nstateless\nisolees ?"}
M -->|"Oui"| N["Serverless pour\nces composants"]
M -->|"Non"| H L'arbre se lit de haut en bas. À chaque nœud, le signal le plus discriminant est vérifié. La question n'est jamais "quelle est la meilleure topologie ?" mais "quel est le signal le plus fort dans mon contexte actuel ?".
Signaux d'équipe¶
La taille et la maturité de l'équipe sont les critères les plus sous-estimés. La topologie du système doit correspondre à la réalité organisationnelle, pas a un idéal technique.
Taille de l'équipe¶
| Taille | Topologie recommandee | Raison |
|---|---|---|
| 1-3 personnes | Monolithe modulaire ou serverless | Pas de capacité a gérer la complexité opérationnelle des microservices |
| 4-10 personnes | Monolithe modulaire | La communication directe suffit, les frontieres de modules sont gérées par la discipline de l'équipe |
| 10-30 personnes | Monolithe modulaire vers microservices | La coordination devient coûteuse, l'autonomie des sous-équipes justifie l'extraction de services |
| 30+ personnes | Microservices | Plusieurs équipes autonomes avec leurs propres cycles de release |
Maturité opérationnelle¶
La maturité opérationnelle est un prérequis, pas un détail. Une équipe sans CI/CD automatisee qui deploie des microservices finira par déployer un monolithe distribué — les releases exigeront une coordination manuelle entre équipes.
| Signal de maturité | Prérequis pour |
|---|---|
| Déploiement automatise (CI/CD) | Microservices, serverless |
| Monitoring et alerting centralises | Microservices, event-driven |
| Infrastructure as Code | Microservices, serverless |
| Contract testing | Microservices |
| Incident response rodee | Microservices, event-driven |
Investir dans la maturité avant de changer de topologie
Si les prérequis ne sont pas la, ameliorez-les avant de migrer. Un monolithe modulaire avec une CI/CD solide, du monitoring et de l'IaC est une meilleure base pour une future extraction en microservices qu'un passage premature.
Signaux de trafic¶
Le profil de trafic influence fortement le choix de topologie.
Trafic constant et prévisible :
- Monolithe modulaire ou conteneurs always-on
- Le scaling horizontal classique (ajouter des instances) suffit
- Le serverless est possible mais pas économiquement optimal
Trafic avec des pics imprévisibles :
- Serverless pour les composants exposes aux pics
- Event-driven pour absorber les pics via des files d'attente
- Les services always-on doivent être sur-provisionnes pour encaisser les pics, ce qui coute cher en creux
Trafic differentiel par composant :
- Un composant reçoit 100x plus de trafic que les autres
- C'est le signal le plus fort pour les microservices : extraire ce composant en service indépendant avec son propre scaling
- Le reste peut rester dans un monolithe modulaire
Trafic nul la plupart du temps :
- Scale-to-zero du serverless est idéal
- Pas de coût fixe en l'absence de trafic
- Acceptable si le cold start de quelques centaines de millisecondes est toléré
Signaux de conformité¶
Les exigences reglementaires et de conformité imposent des contraintes sur la topologie.
| Exigence | Impact sur la topologie |
|---|---|
| RGPD — droit à l'effacement | Plus simple dans un monolithe (une seule base), complexe en microservices (propagation de la suppression a N services) |
| PCI-DSS — isolation des données de paiement | Favorise l'extraction du composant paiement en service isole avec son propre périmètre de conformité |
| SOC 2 — audit trail | L'event-driven et l'event sourcing fournissent un audit natif |
| Souveraineté des données | Certains composants doivent tourner dans une region spécifique — le microservice permet cette séparation géographique |
| Certification sectorielle (sante, finance) | L'isolation du périmètre certifie est plus simple avec un service dédié |
La conformité est un critère qui peut a lui seul justifier une extraction. Si le périmètre PCI-DSS est un module dans un monolithe, tout le monolithe est dans le périmètre PCI-DSS. Extraire le paiement en service isole réduit le périmètre de conformité — et donc le coût et la complexité des audits.
Conway's Law comme force structurante¶
Conway's Law n'est pas une observation folklorique — c'est une force qui agit même si on l'ignore.
"Les organisations qui concoivent des systèmes sont contraintes de produire des systèmes dont la structure est une copie de la structure de communication de l'organisation." — Melvin Conway, 1967
En pratique, ca signifie que la topologie du système finira par reflecter la structure des équipes. Si on a 3 équipes, on aura 3 services (ou 3 gros modules). Si on a 1 équipe, un monolithe est naturel. Forcer une topologie qui ne correspond pas à l'organisation creera du frottement permanent.
Le Reverse Conway Maneuver¶
Au lieu de subir Conway's Law, on peut l'utiliser comme levier. On reorganise les équipes pour que leur structure de communication produise l'architecture souhaitee.
graph TB
subgraph "Conway classique"
O1["Equipe A + B + C\n(une equipe)"] --> S1["Monolithe"]
end
subgraph "Reverse Conway"
O2["Equipe Catalog"] --> S2["Catalog Service"]
O3["Equipe Orders"] --> S3["Order Service"]
O4["Equipe Payments"] --> S4["Payment Service"]
end Le Reverse Conway Maneuver fonctionne, mais il a un prérequis : les équipes doivent être suffisamment grandes pour fonctionner en autonomie (5-8 personnes par équipe minimum, avec toutes les compétences nécessaires). Si on découpé 6 personnes en 3 équipes de 2, on n'aura pas l'autonomie — on aura des goulets d'étranglement.
Les topologies se combinent¶
Un système réel combine souvent plusieurs topologies. Un monolithe modulaire peut publier des événements vers un bus externe. Quelques fonctions serverless peuvent gérer les webhooks entrants. Un service spécifique peut être extrait pour des raisons de scalabilité.
graph TB
subgraph "Systeme hybride"
Client["Client"] --> LB["Load Balancer"]
LB --> MONO["Monolithe modulaire\n(coeur metier)"]
MONO --> DB[("PostgreSQL")]
MONO -->|"events"| BUS["Kafka"]
BUS --> ANALYTICS["Analytics Service\n(microservice)"]
BUS --> LAMBDA["Notifications\n(Lambda)"]
WEBHOOK["Webhooks\nexternes"] --> LAMBDA2["Webhook Handler\n(Lambda)"]
LAMBDA2 -->|"event"| BUS
end L'important est que chaque choix soit explicite et justifie, pas qu'il soit pur. Un monolithe modulaire avec des fonctions serverless pour les tâches périphériques est une architecture parfaitement valide — et souvent optimale.
Documenter les choix
Chaque décision de topologie doit être documentee dans un ADR (Architecture Décision Record) : quel choix, pourquoi, quelles alternatives ont été evaluees, quels signaux ont été considérés. L'ADR est la mémoire du projet — il evite de revisiter les mêmes debats tous les 6 mois.
Chapitre suivant : Bounded contexts — decomposition fonctionnelle, context mapping et DDD strategique.