Quand on développe une application à base de microservices, on doit s’assurer que chaque microservice a toutes les données dont il a besoin pour traiter toutes les requêtes des clients.
Imaginons que l’on veut développer une application de boutique en ligne utilisant le modèle d’architecture Microservices. La plupart des services doivent conserver les données dans une sorte de base de données. Par exemple, le service de commande stocke des informations sur les commandes et le service client stocke des informations sur les clients.
Le problème peut être posé en ces termes: quelle approche adopter pour les bases de données, pour une application à base de microservices, en tenant compte des contraintes et exigences suivantes:
- Les services doivent être faiblement couplés afin d’être développés, déployés et mis à l'échelle indépendamment
- Certaines transactions d’affaires doivent appliquer des invariants couvrant plusieurs services, par exemple, dans l’application du commerce en ligne, le cas d'utilisation « Passer une commande » doit vérifier qu'une nouvelle commande ne dépassera pas la limite de crédit du client. D’autres transactions doivent mettre à jour les données dispersées dans plusieurs services.
- Certaines transactions d’affaires doivent interroger des données appartenant à plusieurs services. Par exemple, le cas d’utilisation « Afficher le crédit disponible d’un client » doit interroger le service Client pour trouver la limite de crédit et le service Commande pour calculer le montant total des commandes ouvertes par le client.
- Certaines requêtes doivent joindre des données appartenant à plusieurs services. Par exemple, trouver des clients dans une région particulière et leurs commandes récentes nécessite une jonction entre les clients et les commandes.
- Les bases de données doivent parfois être répliquées et partitionnées pour optimiser certaines requêtes
- Certains services ont des exigences de stockage de données spécifiques. Pour certains services, une base de données relationnelle est le meilleur choix. D'autres services peuvent avoir besoin d'une base de données NoSQL comme MongoDB par exemple, qui est plus adapté pour stocker des données complexes et non structurées, ou Neo4J, qui est conçue pour stocker et interroger efficacement les données graphiques.
Dans les milieux des microservices,
il existe 2 approches de solution à ce problème
La première approche est le modèle
base de données par service.
Dans cette approche, chaque microservice gère ses propres
données. Cela implique qu'un microservice ne peut pas accéder directement aux
données d’un autre. La communication ou l'échange de données n’est alors
possible qu’à travers un ensemble d'API bien définies.
Contrairement aux apparences, implémenter ce modèle est loin
d’être facile.
En effet, si les contextes sont mal délimités, comme c’est
souvent le cas en général, les microservices auront besoin de données des uns
les autres pour implémenter leur logique d’affaires, ce qui va conduire à des
interactions de type spaghetti entre différents services de l’application.
Le succès de ce modèle dépend d’une définition efficace des
contextes délimités du domaine d’affaire de l’application. Ce découpage est
relativement plus facile à faire pour une nouvelle application. Mais pour les
gros systèmes monolithiques que l’on est en train de migrer vers les
microservices, c'est plus compliqué.
D'autres défis incluent la mise en œuvre des transactions
qui impliquent plusieurs microservices et la mise en œuvre des requêtes qui
manipulent des données provenant de deux ou trois contextes délimités différents.
Si la mise en œuvre de ce pattern est faite proprement, le principal avantage est un couplage lâche entre les microservices. En outre, on peut mettre à jour ou faire évoluer les microservices individuellement, et les équipes de développeurs ont aussi la liberté de choisir une solution de base de données spécifique pour un microservice donné.
La deuxième approche de solution est le modèle « base de
données partagée ».
Une base de données partagée peut être une option viable si les défis liés à la base de données par service deviennent trop difficiles à gérer. Il s'agit d'une option peu risquée pour mieux regrouper les données qui étaient dans le monolithe dans le cas d’une migration vers les microservices. Elle aide également à implémenter facilement les transactions dites ACID, c’est-à-dire les transactions Atomiques, Cohérentes, Isolées et Durables. Notons que pour implémenter les transactions ACID dans l’approche précédente, le pattern SAGA est souvent utilisé.
Le modèle « base de données partagée » tente de résoudre les
mêmes problèmes que le premier, mais en adoptant une approche un peu moins
radicale qui est l’utilisation d’une base de données partagée accessible par
plusieurs microservices.
Cependant, cette approche supprime la plupart des avantages
des microservices. Les développeurs de toutes les équipes doivent coordonner
les modifications de schéma des tables. Il peut également y avoir des conflits
d'exécution lorsque plusieurs services tentent d'accéder aux mêmes ressources
de base de données.
Dans l'ensemble, cette approche peut faire plus de mal que
de bien à long terme.
Certains praticiens la considèrent d’ailleurs comme un anti-pattern.
Pour apprendre davantage sur les patterns 'base de données' pour la conception des microservices, reportez-vous à ce cours sur la plateforme Udemy : Le patterns de conception des microservices
Pour comprendre le processus de conception d'une architecture de microservices, reportez-vous à ce cours sur la plateforme Udemy : Conception d’une architecture de microservices
Références:
Aucun commentaire:
Enregistrer un commentaire