Permettez-moi d’annoncer les candidats. Dans le coin rouge se trouve un ancien champion en titre dans une catégorie des super-lourds – M. Monolith. Dans le coin bleu se trouve un gang jeune et gonflé de microservices dans une catégorie poids plume.
J’ai vu plusieurs monolithes sérieux dans ma vie. L’un d’eux avait environ plus de 5 heures de temps de construction, et l’entreprise a dû créer son propre CI pour continuer à aller de l’avant.
D’un autre côté, j’ai vu des gens utiliser une architecture de microservices. Ils avaient besoin de 17 équilibreurs de charge pour que leur application pré-Alpha soit opérationnelle. La partie amusante est que c’était avant l’ère de l’infrastructure en tant que code, donc c’était un nombre très élevé.
Si vous me demandiez il y a environ cinq ans, je dirais par défaut que le monolithe est mauvais et que les microservices sont bons (et je citerais toutes les choses standard). Cependant, l’expérience pratique de ces années m’a appris que la voie des microservices peut facilement se retourner contre eux.
Problèmes avec les microservices
Permettez-moi de ne pas parler des problèmes de monolithe (cela n’a pas de sens de battre le cheval mort), et laissez-moi me concentrer un peu sur les problèmes liés aux microservices :
- Il y a beaucoup de choses au-delà du codage qui doivent être faites pour avoir un produit prêt (création d’une version, exécution de tests, déploiement, surveillance, mise à l’échelle, etc.). Tout cela doit être compris une seule fois pour un monolithe. Cependant, il doit être répété pour chacun des microservices. Dans le meilleur des cas, vos microservices sont basés sur une pile technologique similaire pour la réutilisation. Dans le pire des cas, vous devrez réinventer la roue pour chacun d’eux. (Une petite note : Certaines de ces douleurs sont progressivement résolues par l’outillage, mais seulement certaines d’entre elles).
- Qui doit se réveiller à 2 heures du matin si votre service se met à boiter ? Une équipe d’opérations dédiée au monolithe a généralement suffisamment de connaissances pour résoudre le premier niveau de problèmes (et vous permettre de gérer le reste à 8 heures). Dès que vous avez des centaines de microservices, vous vous retrouvez assez souvent avec quelques personnes (ou peut-être même une seule) qui savent comment maintenir ce service spécifique en vie. Ce n’est pas amusant d’être réveillé à 2 heures du matin juste parce que certains moniteurs ont eu un faux positif. En outre, cela augmente incroyablement les risques opérationnels : que se passe-t-il lorsque cette personne qui connaît un microservice spécifique est en vacances quelque part sans Internet ?
- Déplacer du code dans un monolithe et changer d’interface n’est généralement pas si mal. Le déplacement de code entre les microservices et les interfaces changeantes (y compris la gestion des versions et la compatibilité descendante) est incroyablement coûteux.
- Cette histoire de changement d’interface devient particulièrement pénible si vous n’avez pas parfaitement partitionné votre application la première fois et constatez que certains éléments de logique appartiennent au mauvais microservice (je peux vous promettre que vous ne l’avez pas parfaitement partitionné). Il serait naïf de supposer que la réflexion initiale (qui a probablement été mise en œuvre dès le premier jour) sera parfaitement correcte pour les années suivantes.
- Monolith utilise le même langage, le même framework, etc. En conséquence, déplacer des personnes entre les parties d’un monolithe est facile. Il est difficile de déplacer des personnes entre différents microservices (qui peuvent avoir des piles technologiques très différentes).
- Le débogage de quelque chose sur un ensemble de microservices est pour le moins pénible. Quiconque devait chasser un bogue sur 4 à 5 microservices pendant des jours pour découvrir que l’un d’entre eux n’avait pas effectué de validation comprendrait.
Je suis presque sûr qu’il y a beaucoup d’autres inconvénients. Cependant, même cette liste me fait remettre en question les microservices comme une panacée.
D’accord. Le monolithe est mauvais. Les microservices sont mauvais… Ahhhh… Tout est mauvais. Il n’y a nulle part où courir. Qu’est-ce qu’on fait?
Qu’est-ce qu’on fait?
Le plus gros problème n’est pas le monolithe en soi (ou les microservices en soi), mais plutôt les extrêmes qui en résultent. Et malheureusement, les équipes/entreprises peuvent ne pas reconnaître les problèmes à temps et commencer à les résoudre jusqu’à ce qu’ils deviennent complètement incontrôlables.
Monolith devient grand et a tendance à continuer à croître et à s’aggraver. Lorsque vous réalisez que c’est un problème, il est déjà si gros et velu que le décomposer devient une tâche presque impossible.
Les microservices sont souvent utilisés prématurément, ils croissent en nombre et en complexité de leurs interactions. En conséquence, il apporte tous les problèmes que j’ai décrits ci-dessus.
Mon point de vue est le suivant : vous devez avoir des services à la bonne taille © 🙂 Tout d’abord, je pense qu’une bonne idée est de commencer avec une architecture raisonnablement monolithique (un ou plusieurs services). Au fur et à mesure qu’ils ont commencé à se développer, recherchez les fissures naturelles (morceaux de code avec des attributs très différents). Ce sont les éléments qui pourraient être progressivement séparés en services autonomes.
Par exemple, je travaillais sur un service back-end, et nous avons constaté qu’une partie était appelée beaucoup plus souvent que d’autres. Il doit évoluer horizontalement de manière plus agressive que les autres. De plus, nous avons constaté que l’architecture actuelle de cette pièce était un peu problématique et qu’elle comportait un nombre raisonnablement faible de dépendances vis-à-vis du reste du backend. Ici, vous avez un candidat parfait à extraire en tant que service séparé.
Avertissements supplémentaires
Deux avertissements/notes supplémentaires :
- Gardez un œil sur le monolithe. Il est facile de rater le point quand il devient incontrôlable. Il vaut mieux commencer à séparer les choses un peu prématurément que de le faire trop tard. Mon intuition est que dès que vous commencez à passer environ 5% de votre temps à lutter contre les problèmes de monolithe, il est temps de faire quelque chose.
- De nombreuses entreprises sont très résistantes aux efforts de refactoring non triviaux. Il vient de plusieurs endroits. Les ingénieurs aiment toujours remanier les choses, que ce soit nécessaire ou non. En conséquence, la direction est assez sceptique à ce sujet. De plus, les grandes refactorisations ou réécritures augmentent le risque (ce que les gestionnaires n’aiment pas). Je vous recommanderais de commencer à vous préparer dès le départ (en prenant en compte les avantages, les étapes, la minimisation des risques, etc.). Cela permet d’obtenir un consensus et d’être prêt à exécuter.
Conclusion
Il est difficile de dire qui gagne dans ce combat entre monolithe et microservices. Vous devez équilibrer les deux en commençant par le simple (monolithe) et en évoluant vers la séparation des complexités (microservices).