L’architecture Monolith a très bien réussi à façonner le monde du logiciel tel que nous le voyons aujourd’hui. Cependant, ces dernières années ont vu une forte baisse de son adoption, notamment avec l’avènement des Microservices. La popularité des microservices a été causée par le besoin d’évolutivité et d’évolutivité, qui à son tour est causé par la pénétration de l’informatique dans presque toutes les entités, animées ou inanimées. Les applications modernes ne voient aucune limite en matière de mise à l’échelle et ces applications aiment le changement et c’est là que Monolith ne convient pas du tout.
Les microservices, du moins en théorie, sont « The Silver Bullet » qui résoudront tous les problèmes et serviront l’humanité jusqu’à l’éternité, mais cela n’arrive pas. Les microservices apportent de nombreux défis qui n’existaient pas auparavant. Pourtant, ce qu’il fait, il le fait magnifiquement et efficacement et, surtout, sert le but.
L’idée populaire est d’avoir des services très fins où chaque service est responsable d’une seule tâche. Les praticiens jettent un regard méprisant sur les services grossiers car ils sont jugés contraires à la philosophie des microservices et c’est là que Monolith est laissé pour une mort lente. Le monolith est-il vraiment si mauvais et si c’est le cas, en quoi a-t-il été l’une des architectures les plus réussies depuis des années ?
Monolithique et Microservice
Les microservices à granularité fine ont leurs propres défis, par exemple les transactions ou la latence. Pour aggraver les choses, les frais généraux de gestion sont écrasants, et accepter la finesse n’est pas une tâche facile. Les microservices à granularité fine sont préférés car il n’y a pas de point de défaillance unique, la possibilité d’évoluer indépendamment, la possibilité de changer et de déployer souvent, et la liste est longue. Cependant, si vous examinez attentivement ces avantages, tout cela ne peut être réalisé que par des modèles de conception complexes et une discipline de développement. D’un autre côté, il existe des défis tels que la latence inévitable du réseau qui à son tour entraîne une dégradation des performances (à moins qu’il n’utilise des systèmes complexes supplémentaires comme la mise en cache), une surcharge de gestion énorme, des transactions complexes et bien d’autres.
Un monolithe par définition est un système qui se compose de toutes les parties d’un système, mais depuis des lustres, les organisations ont construit des monolithes qui ont au moins des processus différents pour l’interface utilisateur et le backend et ces parties s’intègrent via des interfaces. Ce modèle séparé est mentionné ici.
Les systèmes Monolith ont l’avantage en matière de simplicité. Si le processus de développement peut d’une manière ou d’une autre éviter de le transformer en une grosse boule de boue et si un système monolithique (tel que défini ci-dessus) peut être divisé en sous-systèmes de telle sorte que chacun de ces sous-systèmes soit une unité complète en soi, et si ces les sous-systèmes peuvent être développés dans un style de microservices, nous pouvons tirer le meilleur parti des deux mondes. Ce sous-système n’est rien d’autre qu’un « service grossier », une unité autonome du système.
Un service à grain grossier peut être un point de défaillance unique. Par définition, il se compose de sous-parties importantes d’un système et sa défaillance est donc hautement indésirable. Si une partie de ce service à granularité grossière échoue (qui autrement aurait été un service à granularité fine lui-même), il doit prendre les mesures nécessaires pour masquer la défaillance, la récupérer et la signaler. Cependant, les problèmes commencent lorsque ce service à gros grains échoue dans son ensemble. Pourtant, ce n’est pas le facteur décisif et si le bon mécanisme est en place pour une haute disponibilité (conteneurisé, multi-zone, multi-région, sans état), il y aura de très faibles chances pour cela. D’un autre côté, cela élimine la complexité de la gestion des défaillances pour les sous-parties comme la nécessité d’utiliser des disjoncteurs. Il y a un compromis mais il vaut la peine d’être évalué.
La mise à l’échelle d’un service à grain grossier n’est pas très différente d’un service à grain fin. Si ses limites sont définies avec soin et s’il est développé comme un apatride, la mise à l’échelle de ces services est triviale. Ils peuvent s’exécuter à l’intérieur de conteneurs et peuvent même être déployés sans serveur sur le cloud (par exemple, AWS Fargates).
L’un des défis auxquels un service à gros grains est confronté est de réagir au changement. Autrefois, à l’époque du Monolith, le trajet du code à la production était manuel et fastidieux. Cependant, avec les méthodologies modernes, il peut être automatisé facilement. Un service à gros grains n’est pas très fin, mais il n’est pas censé être à l’échelle d’un monolithe et donc réagir à ce changement n’est pas si difficile qu’il y paraît. Il peut encore y avoir des compromis, mais cela vaut la peine de les considérer.
Un service à gros grains est souvent une unité complète en soi et peut donc tirer parti de son exécution dans un seul processus, ce qui signifie que les appels réseau peuvent être remplacés par des appels de méthode qui améliorent non seulement les performances, mais simplifient également la gestion des composants.
Conclusion
De toute évidence, il existe un besoin d’un amalgame entre un Microservice et un Monolith. En fait, les microservices ne consistent pas vraiment à créer de très petits services, mais c’est un style d’architecture pour créer un logiciel en tant qu’application de service qui peut être construit indépendamment et qui interagit via des interfaces. Tout cela peut être tissé dans un monolithe ou un service à gros grains qui permet de récolter les bénéfices du style architectural.
Et donc, Monolith n’est pas mort mais il s’est juste incarné sous une forme différente pour servir pour le temps à venir.