Architectures monolithique et de microservices
Fabrikam a intégré son nouveau service de drone dans son application existante. Ils se rendent compte que cette solution n’est pas un bon plan à long terme pour leur application. Le système existant est une architecture monolithique, mais qu’est-ce que cela signifie exactement ?
Qu’est-ce qu’une architecture monolithique ?
Une architecture monolithique est une architecture dans laquelle tous les composants d’une application sont colocalisés au sein d’une même unité. Cette unité est généralement restreinte à une instance de runtime unique de l’application. Les applications traditionnelles se composent souvent d’une interface web, d’une couche de services et d’une couche de données. Dans une architecture monolithique, ces couches sont combinées sur une instance de l’application.
Les architectures monolithiques sont souvent des solutions appropriées pour les petites applications, mais elles peuvent devenir peu maniables lorsque l’application croît. Ce qui était à l’origine une petite application peut rapidement devenir un système complexe difficile à mettre à l’échelle, difficile à déployer et difficile à améliorer.
Tous les services sont contenus dans une seule unité. Cette organisation pose des défis pour la croissance de l’activité de la société et de sa charge système. Voici quelques-uns de ces défis :
- Difficulté à mettre à l’échelle les services de façon indépendante.
- Complexité du développement et de la gestion des déploiements au fur et à mesure que le code base se développe, ce qui ralentit l’implémentation des nouvelles versions et fonctionnalités.
- L’architecture est liée à une seule pile technologique, ce qui limite l’innovation pour de nouvelles plateformes et de nouveaux SDK.
- Les mises à jour du schéma de données peuvent être de plus en plus difficiles.
Ces défis peuvent être relevés en examinant d’autres architectures, telles qu’une architecture de microservices.
Qu’est-ce qu’une architecture de microservices ?
Une architecture de microservices se compose de petits services indépendants et faiblement couplés. Chaque service peut être déployé et mis à l’échelle indépendamment.
Un microservice est suffisamment petit pour qu’une équipe réduite de développeurs puisse l’écrire et en assurer la maintenance. Comme les services peuvent être déployés indépendamment, une équipe peut mettre à jour un service existant sans avoir à recréer ni redéployer l’application entière.
Chaque service est habituellement responsable de ses propres données. Sa structure de données est isolée, de sorte que les mises à niveau et les modifications apportées au schéma ne dépendent pas d’autres services. Les demandes de données sont généralement gérées via des API et fournissent un modèle d’accès bien défini et cohérent. Les détails de l’implémentation interne sont masqués pour les consommateurs de service.
Comme les services sont indépendants, ils peuvent utiliser différents kits SDK, piles de technologies et infrastructures. Il est courant de voir des services s’appuyer sur des appels REST pour la communication entre les services en utilisant des API bien définies, au lieu d’appels de procédure distante (RPC) ou d’autres méthodes de communication personnalisées.
Les architectures de microservices sont indépendantes des technologies, mais vous verrez souvent des conteneurs ou des technologies serverless utilisés pour leur implémentation. L’intégration continue et le déploiement continu (CI/CD) sont fréquemment utilisés pour augmenter la vitesse et la qualité des activités de développement.
Avantages d’une architecture de microservices
Pourquoi choisir une architecture de microservices ? Une architecture de microservices présente plusieurs avantages principaux :
- Agilité
- Code réduit, petites équipes
- Mélange de technologies
- Résilience
- Scalabilité
- Isolation des données
Agilité
Les microservices sont déployés de manière indépendante, ce qui facilite la gestion des correctifs de bogues et des nouvelles fonctionnalités. Vous pouvez mettre à jour un service sans avoir à redéployer l’application entière et effectuer une restauration si une mise à jour est source de problèmes. Dans de nombreuses applications traditionnelles, si un bogue est détecté dans une partie de l’application, il peut bloquer l’intégralité du processus de publication. Par conséquent, de nouvelles fonctionnalités peuvent être retenues en attendant l’intégration, le test et la publication d’une résolution de bogue.
Code réduit, petites équipes
Un microservice doit être suffisamment petit pour qu’une seule équipe de fonctionnalité puisse le générer, le tester et le déployer. Les petits codes base sont plus faciles à comprendre. Dans une application monolithique, les dépendances de code tendent à s’emmêler au fil du temps. L’ajout d’une nouvelle fonctionnalité nécessite de toucher au code à de nombreux endroits. Une architecture de microservices réduit les dépendances en ne partageant pas du code ou des magasins de données. Cela facilite l’ajout de nouvelles fonctionnalités.
Les petites équipes permettent également une plus grande souplesse. Selon la règle des « deux pizzas », une équipe doit être suffisamment réduite pour que deux pizzas suffisent à rassasier tous ses membres. Évidemment, ce n’est pas une métrique exacte et tout dépend de l’appétit de l’équipe ! Mais il faut en retenir que les grands groupes ont tendance à être moins productifs, car la communication est plus lente, la charge de gestion augmente et l’agilité diminue.
Mélange de technologies
Les équipes peuvent opter pour les technologies qui se prêtent le mieux à leur service. Elles peuvent utiliser une combinaison de piles technologiques, le cas échéant. Chaque équipe peut faire évoluer les technologies qui prennent en charge son service indépendamment. Les services peuvent utiliser différents langages de développement, services cloud, kits SDK, etc., en raison de cette indépendance. Les équipes peuvent sélectionner les meilleures options pour leur service, tout en réduisant au minimum l’effet externe sur les consommateurs du service.
Résilience
Si un microservice individuel devient indisponible, il ne perturbe pas l’application tout entière, dès lors qu’un microservice en amont est conçu pour gérer correctement les défaillances (par exemple en implémentant une coupure du circuit). L’avantage pour vos utilisateurs ou les consommateurs des services est une expérience toujours active pour votre application.
Scalabilité
Une architecture de microservices permet de mettre à l’échelle chaque microservice indépendamment des autres. Vous pouvez effectuer monter en charge les sous-systèmes qui nécessitent plus de ressources, sans appliquer ce changement à toute l’application. Cette organisation améliore les performances globales de votre application. Cela permet également de réduire les coûts. Vous pouvez ajouter des ressources supplémentaires uniquement aux services qui en ont besoin, au lieu de mettre à l’échelle la totalité de votre application.
Isolation des données
Une architecture de microservices renforce la capacité à mettre à jour le schéma de données, car un seul microservice est concerné. Dans une application monolithique, les mises à jour de schéma peuvent devenir difficiles. Différentes parties de l’application peuvent toutes toucher aux mêmes données, ce qui rend les modifications de schéma risquées. Avec une architecture de microservices, vous pouvez mettre à jour un schéma tout en laissant la surface de votre API intacte. Les consommateurs de services ont ensuite la même expérience, quelle que soit l’architecture de données sous-jacente.
Défis potentiels liés à une architecture de microservices
Une architecture de microservices présente de nombreux avantages, mais ce n’est pas tout. Elle apporte aussi son propre ensemble de défis :
- Complexité
- Développement et test
- Manque de gouvernance
- Surcharge du réseau et latence
- Intégrité des données
- Gestion
- Gestion de versions
- Ensemble de compétences
Complexité
Une application de microservices compte plus d’éléments mobiles qu’une application monolithique équivalente. Si chaque service est plus simple, le système dans son ensemble est plus complexe. Avec les outils de découverte des services, d’orchestration et d’automatisation, l’application globale peut comporter plus d’éléments à gérer.
Développement et test
L’écriture d’un petit service qui s’appuie sur d’autres services dépendants demande une approche différente de celle consistant à écrire une application monolithique ou stratifiée traditionnelle. Les outils existants ne sont pas toujours conçus pour fonctionner avec des dépendances de services. Refactoriser au-delà des limites des services peut s’avérer difficile. Il est également difficile de tester les dépendances de services, notamment quand l’application évolue rapidement.
Manque de gouvernance
L’approche décentralisée de création de microservices présente des avantages, mais elle peut aussi être une source de problèmes. Vous pouvez en effet vous trouver face à une diversité de langages et de frameworks telle que l’application devient difficile à gérer. Il peut être utile de mettre en place certains standards à l’échelle du projet, sans trop limiter la flexibilité des équipes. Le besoin de normes uniformes vaut notamment pour les fonctionnalités transversales, telles que la journalisation et les métriques.
Surcharge du réseau et latence
l’utilisation de nombreux services granulaires de petite taille peut se traduire par une intensification des communications entre les services. Si la chaîne des dépendances des services devient trop longue (par exemple le service A appelle le service B, qui appelle le service C, etc.), la latence supplémentaire de ces appels réseau peut devenir un problème. Concevez vos API avec soin. Évitez les API trop bavardes, envisagez des formats de sérialisation et cherchez à utiliser des modèles de communication asynchrone.
Intégrité des données
Chaque microservice étant responsable de la persistance de ses propres données. Ainsi, la cohérence des données peut être une gageure. Adoptez la cohérence éventuelle dans la mesure du possible. Vous pouvez également vous retrouver avec des données dupliquées et une immense architecture de données. Cette situation peut augmenter les coûts de stockage brut, ainsi que les coûts de service pour la plateforme de données avec la duplication des services et des données.
Gestion
Une expérience réussie avec les microservices exige une culture DevOps mature. La mise en place d’une journalisation corrélée entre les services peut poser des problèmes. En règle générale, la journalisation doit mettre en corrélation plusieurs appels de services pour une même opération utilisateur.
Gestion de versions
Les mises à jour apportées à un service ne doivent pas perturber les services qui en dépendent. Plusieurs services peuvent être mis à jour à un moment donné. Sans une conception minutieuse, vous risquez de rencontrer des problèmes de compatibilité descendante ou ascendante. Les services qui ont un retard sur l’adoption de nouvelles versions d’API peuvent augmenter les ressources et la maintenance requises pour les API plus anciennes.
Ensemble de compétences
Les microservices sont des systèmes hautement distribués. Ces systèmes distribués nécessitent souvent un ensemble de compétences différent pour assurer un développement, une gestion et une maintenance corrects. Évaluez avec soin les chances de réussite en tenant compte des compétences et de l’expérience de l’équipe. Accordez à vos équipes le temps de planification nécessaire pour faire évoluer leurs capacités.
Quand faut-il choisir une architecture de microservices ?
Au vu de toutes ces informations contextuelles, quelles sont les situations où une architecture de microservices convient le mieux ?
- Les grandes applications qui demandent une grande rapidité de publication.
- Applications complexes qui doivent être très scalables.
- Applications avec des domaines riches ou de nombreux sous-domaines.
- Une organisation constituée de petites équipes de développement.