dimanche 3 mai 2020

Architecture Monolithique: forces et faiblesses

Dans le domaine de l’ingénierie logicielle, une architecture est dite monolithique lorsqu'elle centralise tous les traitements du logiciel au sein d’une même unité applicative. Une telle architecture possède un avantage dans le cas du développement d’applications simples, mais le prix à payer est lourd sur le moyen et long termes. Les évolutions logicielles sont de plus en plus difficiles à déployer au fur et à mesure que les besoins évoluent. L'implémentation d'un changement, même le plus simple, est susceptible de se transformer en un projet complexe, car les composants de l'application sont devenus fortement interdépendants et la modularité s'est dégradée. Par ailleurs, les nouveaux besoins ne peuvent pas être satisfaits par ces architectures fortement centralisées. La recherche des solutions à ces limitations est à l’origine de l’émergence des architectures basées sur les services en général, et des microservices en particulier. Dans cet article, je présente le concept des architectures monolithes, un exemple d'application construite suivant cette approche, ainsi que ses avantages et ses limites.

Introduction

La plupart des systèmes d’informations d'entreprises sont bâtis autour des applications Web classiques construites suivant un style architectural dit «monolithique». Au sein d’une même unité applicative, on retrouve l’interface utilisateur; les unités de traitement qui exécutent la logique spécifique au domaine d'affaires, qui gèrent les requêtes HTTP, qui récupèrent et mettent à jour les données dans les référentiels et qui remplissent les vues HTML et les envoient au navigateur. Tout ceci regroupé au sein d’un seul exécutable logique qui, très souvent, est un seul fichier (cas de JAVA et .Net) ou une seule arborescence de répertoires (cas de Node.js et autres).
Les applications construites suivant ces modèles sont aussi appelées les monolithes. Dans une telle application, la moindre modification nécessite une mise à jour complète de la version, avec son propre cycle de validation, ce qui peut potentiellement ralentir de nombreuses équipes en aval. Aussi, si la mise à jour d'une partie de l'application provoque des erreurs, il faut placer l'ensemble hors ligne pour annuler les modifications et résoudre le problème.

Exemple d’une architecture monolithique

Imaginons qu’on veuille créer une application de commerce électronique qui prend les commandes des clients, vérifie les stocks et les crédits disponibles et les expédie. L'application sera constituée de plusieurs composants, dont une interface utilisateur, ainsi que des traitements pour vérifier le crédit, mettre à jour l'inventaire et expédier les commandes.

architecture monolithique
Exemple d'une architecture monolithique
Si on décide d’adopter une approche monolithique pour une telle application, l’architecture peut être représentée comme sur la figure ci-dessus.
En général, lors de la conception, on utilise les fonctionnalités de base du langage de programmation pour diviser l'application en classes, en fonctions et en espaces de noms. Sur cet exemple, on peut imaginer un espace de nom pour la gestion des comptes, un espace de nom pour l’inventaire et un autre pour les commandes. Le traitement d’une demande jusqu’à l’expédition en passant la vérification du stock et du crédit et la mise à jour de l’inventaire se fait dans un seul processus. Le code source de toute l'application est structuré au sein d'une seule unité de déploiement. On peut deviner sur notre exemple que c’est une application Web Java. En effet, l’unique fichier de déploiement de l’application est d'extension « .war » . On peut aussi constater qu’il est déployé dans un conteneur Tomcat. Si le développement avait été fait avec ASP.NET, on aurait déployé un seul fichier d'extension « .ear » dans un serveur Microsoft IIS par exemple. De même, si on avait choisi de développer avec Node.JS, on aurait déployé juste une arborescence de répertoires. On peut voir que l’ensemble des traitements de l’application accède à une seule base de données. Notons qu’il est possible de mettre à l'échelle horizontalement cette application en exécutant de nombreuses instances derrière un équilibreur de charge.

Les forces

Les architectures monolithiques ont quelques avantages.

Elles sont simples à développer

En effet, les plateformes de développement qui existent ont été conçues essentiellement pour soutenir le développement d'applications monolithiques. De multiples assistants y ont été incorporés au fil des années pour faciliter le travail des développeurs.

Elles sont simples à déployer

Il suffit de déployer un seul fichier ou une seule arborescence de répertoires du code source sur le serveur d’application approprié.

Elles sont simples à mettre à l'échelle

Il est facile de mettre à l'échelle l'application en exécutant plusieurs copies de l'application derrière un équilibreur de charge.

Les limites

Malgré les quelques avantages cités précédemment, une fois que la taille de l'application a augmenté et que l'équipe s'est agrandie, cette approche présente un certain nombre d'inconvénients qui peuvent devenir critiques avec le temps.
La grande quantité de code du monolithe intimide et décourage certains développeurs, en particulier ceux qui sont nouveaux dans l'équipe
L'application peut être difficile à comprendre et à modifier. En conséquence, le développement ralentit généralement. De plus, comme il n'y a pas de frontières rigides entre les modules, la modularité se dégrade au fil du temps. Aussi, comme il peut être difficile de comprendre comment mettre en œuvre correctement un changement, la qualité du code se dégrade avec le temps. C’est une spirale descendante.

La surcharge de l’IDE (ou plateforme de développement)

Plus la quantité de code sous-jacent à une application est grande, plus la plateforme (l'IDE) est lente et les développeurs moins productifs.

Le ralentissement du chargement de l’application au démarrage

Cela a eu un impact énorme sur la productivité des développeurs en raison du temps perdu à attendre le démarrage du conteneur. Cela affecte également le déploiement.
Le déploiement continu est difficile
Une large application monolithique est également un obstacle aux déploiements fréquents. Pour mettre à jour un composant, il faut redéployer toute l'application. Le plus souvent, il faut à chaque déploiement déconnecter les utilisateurs, arrêter l’application, déployer avant de redémarrer. Aussi, le code source ayant grossi, le déploiement prend encore plus de temps. Les entreprises qui mettent en ligne les applications de commerce électronique par exemple, ne peuvent pas se permettre des interruptions fréquentes.

La mise à l'échelle de l'application peut être difficile

Une architecture monolithique ne peut évoluer que dans une seule dimension. D'une part, elle peut évoluer avec un volume de transactions croissant en exécutant davantage de copies de l'application. Certains clouds ​​peuvent même ajuster dynamiquement le nombre d'instances en fonction de la charge. D'un autre côté, cette architecture ne peut pas évoluer avec un volume de données croissant. Chaque copie de l'instance d'application accède à l’ensemble des données, ce qui rend la mise en cache moins efficace et augmente la consommation de la mémoire et le trafic des entrées / sorties. En outre, les composants de l’application ont souvent des besoins en ressources différents - l'un peut être gourmand en CPU tandis qu'un autre peut consommer beaucoup de mémoire. Avec une architecture monolithique, il n’est pas possible de mettre à l'échelle chaque composante indépendamment.

L'obstacle au développement à l'échelle

Une application monolithique est également un obstacle au développement à l'échelle. Une fois que l'application atteint une certaine taille, il est utile de diviser l'organisation d'ingénierie en équipes qui se concentrent sur des domaines fonctionnels spécifiques. Par exemple, nous pourrions souhaiter avoir l'équipe d'interface utilisateur, l'équipe de comptabilité, l'équipe d'inventaire, etc. Le problème avec une application monolithique est qu'elle empêche les équipes de travailler de manière indépendante. Les équipes doivent coordonner leurs efforts de développement et de redéploiement. Il est beaucoup plus difficile pour une équipe de modifier et de mettre à jour la production.
La nécessité d'un engagement à long terme envers une technologie
Une architecture monolithique oblige l’organisation à être mariée à la même technologie de développement (et dans certains cas, à une version particulière de cette technologie), celle qui a été choisie au début du développement. Avec une application monolithique, il peut être difficile d'adopter progressivement une nouvelle technologie. De plus, si l'application utilise une infrastructure de plateforme qui devient par la suite obsolète, il peut être difficile de la migrer progressivement vers une infrastructure plus récente et meilleure. Il est possible que pour adopter une plateforme plus récente, l’on soit obligé de réécrire l'intégralité du code de l'application dans un autre langage de programmation, ce qui est une entreprise risquée.

Conclusion

Les architectures monolithiques ont fait leur temps. Ils ont permis de régler certains problèmes, mais ont montré leurs limites quant au soutien de la transformation et de la modernisation des entreprises face aux nouveaux besoins d’affaires modernes. L’émergence des architectures basées sur les services en général, et sur les microservices en particulier, est une réponse à ces insuffisances.
Pour démarrer avec les microservices, je vous recommande ce cours sur Udemy: Les bases des architectures de microservices Références: [1] Microservices Patterns by Chris Richardson
[2] SOA , microservices et API management - 4e éd : Le guide de l'architecte des SI agiles


Aucun commentaire:

Enregistrer un commentaire