Partie 1 : Comprendre ce qu'est une architecture orientée microservices

Partie 1 : Comprendre ce qu’est une architecture orientée microservices

Les architectures orientées microservices sont de plus en plus utilisées pour le développement de logiciels. La difficulté de maintenir de manière efficace des applications qui présentent une architecture monolithique est souvent mise en avant pour appuyer l’utilisation des architectures orientées microservices. Mais concrètement, que sont les microservices et leur écosystème ? Comment les utiliser au mieux ?

Thèmes d’innovation

Auteurs

Le but de cette série d’articles est de comprendre ce qu’est une architecture orientée microservices, quels en sont ses avantages, quels en sont ses limites/défis et comment les concepts de Service Mesh et API-Gateway font partie de leur écosystème.

Cette série d’articles est définie comme suit :

Comprendre ce qu’est une architecture orientée microservices

Les microservices définissent à la fois un type d’architecture et une approche de développement logiciel qui consiste à découper les applications en composants simples et indépendants les uns des autres.

Ainsi, au lieu d’avoir une application unique, dite “monolithique”, réalisant une multitude de fonctions, une application microservices est composée d’une multitude de composants autonomes réalisant, chacun, une fonction de l’application. Il s’agit donc d’une approche décentralisée, où l’ensemble des composants n’est pas contrôlé d’une manière centrale. Chaque composant est focalisé sur la réalisation d’une fonctionnalité bien définie. Il est un produit à part entière : il peut éventuellement être produit par une équipe différente, avoir une technologie, un cycle de vie spécifique et/ou un déploiement spécifique, ….

Dans une application microservices, la granularité des composants peut varier. Les composants qui concernent la mise en œuvre d’une fonctionnalité se nomment des microservices. Les composants qui concernent la mise en oeuvre de plusieurs microservices ayant un certain couplage entre eux se nomment “miniservices” [1]. Enfin les FaaS [2] concernent des composants ayant une granularité focalisée sur des fonctions.

Dans la suite de l’article nous nous concentrerons uniquement sur les composants dits “microservice”. Les FaaS étant un cas particulier, un article leur sera dédié prochainement.

Les microservices communiquent entre eux via des protocoles réseau en exposant, chacun, une API. Ils peuvent aussi avoir accès à une source de données. L’application microservice est donc composée d’un réseau de microservices.

Avantages et défis d’une application microservices

La caractéristique majeure d’une application microservices vient de sa modularité. Les microservices sont autonomes, orientés fonctionnalité et peuvent être utilisés dans plusieurs contextes différents. Il y a donc une plus grande portabilité tout en pouvant avoir des composants hétérogènes (technologies d’implémentation et langages de programmation différents).

Vu que les microservices doivent être le plus autonome possible, le couplage entre microservices est réduit. Ceci implique pas mal d’avantages dont :

  • une meilleure résilience : moins d’erreurs en cascade entre les microservices
  • une meilleure robustesse : la mise à jour d’un microservice ne perturbe pas le fonctionnement global de l’application (à interface/API identiques)
  • une facilité accrue de mettre en œuvre des tests unitaires : le microservice se focalise sur une fonctionnalité et est autonome.
  • une forte interopérabilité : l’interopérabilité des microservices est une force dans la mesure où l’on est pas verrouillé à une technologie en particulier. On peut utiliser la technologie/l’outil le plus adapté au métier.
  • une scalabilité plus fine : la scalabilité est liée à une fonctionnalité (le microservice), de ce fait, seuls les microservices surchargés pourraient être dupliqués et non l’entièreté de l’application.

Développer une application microservice présente un certain nombre de défis :

  • Le déploiement d’une application microservices peut être rendu difficile quand cette application contient des centaines de microservices. De ce fait, la maîtrise des pipelines de déploiement CI/CD [3] devient particulièrement importante. Le schéma suivant affiche seulement 15 microservices, la complexité du déploiement peut déjà être aisément mise en lumière. Imaginons maintenant une application avec 500 microservices, une pipeline de déploiement devient alors indispensable.

  • Les tests d’intégration peuvent être complexes à mettre en œuvre vu les interactions entre les différents microservices.
  • Plus la modularité d’une application est grande, plus les tâches nécessitant une vue globale du comportement de l’application seront difficiles à mettre en œuvre.
    • La gestion de l’observabilité d’une application microservices est fortement impactée vu que chaque fonction de l’application est gérée d’une manière indépendante (via microservice). Il est donc nécessaire de recourir à des outils permettant de tracer ou d’agréger les logs et métriques des différents microservices afin d’assurer une observabilité globale de l’application.
    • Les besoins non-fonctionnels de l’application doivent parfois être pensés de manière globale et non par microservices (par exemple, les communications entre microservices doivent être sécurisées ; après 3 essais de connexion, envoyer un code d’erreur ; ...). Si une approche globale n’est pas évoquée, une duplication de code entre microservice pourrait se manifester [4].

Bref, plus une application microservices contiendra de microservices, plus la maintenance sera complexe. Dans ce cas, l’écosystème des microservices joue un rôle important en y apportant des solutions comme les Service Mesh et les API-Gateway (ces technologies seront analysées dans la suite de ces articles).

Par rapport à une application monolithique, une application microservices doit passer par une étape supplémentaire avant que l’application soit opérationnelle. Cette étape consiste à assembler les différents microservices pour qu’ils puissent fonctionner ensemble correctement. C’est durant cette étape que l’on doit gérer les aspects non-fonctionnels globaux de l’application.

Le schéma suivant montre une manière naïve de gérer les aspects non-fonctionnels d’une application microservices : des librairies sont incorporées dans chaque microservice afin de gérer la sécurité, l’observabilité ou encore la résilience.

Cette manière de procéder est déjà complexe à réaliser car chaque microservice ne pourrait pas incorporer la même librairie (langage différent) pour gérer un même aspect non-fonctionnel. De plus, s’il s’avère qu’une même librairie peut être utilisée pour différents microservices, ceci engendrerait indéniablement un couplage dû à la configuration et l’injection de ces librairies.

L’idéal serait de gérer les aspects non-fonctionnels de manière transversale et si possible en intégrant des outils permettant de faciliter la maintenance (observabilité, déploiement). Le schéma ci-dessous illustre cette idée.

Cette gestion transversale peut être gérée via les frameworks d’API-Gateway et les Services Mesh.

Les flux de données entre microservices

Avant de comprendre comment assembler des microservices avec un Service Mesh ou une API-Gateway, il est important de discerner 2 types de flux dans une application microservices : les flux internes et les flux externes. Les flux internes (aussi appelés communication ouest-est) sont les flux de données qui s’échangent entre les microservices d’une même application (flux en rouge sur la Figure) ( tandis que les flux externes (ou communication nord-sud) sont les flux de données qui entrent ou qui sortent de l’application microservices (flux en bleu sur la Figure).

Les articles suivants détailleront les principes des Services Mesh et des API-Gateway.

Pour aller plus loin

Les articles suivants permettent d’approfondir les architectures microservices :


Suite suggérée : Partie 2 : Les Services Mesh


Contact

Pour plus d’information veuillez contacter : Fabian Steels ou Valéry Ramon

Keywords : Microservices, architecture, cycle de vie, miniservice, FaaS, modularité, interopérabilité, robustesse, résilience, scalabilité, flux de données, ServiceMesh, API Gateway

[1Cette dénomination est due à des cas bien spécifiques où un couplage entre composants ne peut pas être supprimé.

[2Function-as-a-Service

[3L’intégration continue (CI) et le déploiement continu (CD) sont des pratiques qui permettent d’automatiser la distribution de logiciel : https://www.redhat.com/fr/topics/devops/what-is-ci-cd

[4Il s’agit ici d’un contre-pattern qui doit être éviter