Dans une application d'entreprise traditionnelle, les requêtes des clients sont exécutées dans une transaction de base de données. En règle générale, toutes les données dont vous avez besoin pour effectuer une requête sont stockées dans une base de données unique dotée de propriétés ACID (le terme ACID signifie "atomicité, cohérence, isolation, durabilité"). Par conséquent, vous pouvez garantir la cohérence en utilisant les fonctionnalités transactionnelles du système de base de données relationnelle. En cas de problème lors de la transaction, le système de base de données peut effectuer un rollback et réessayer automatiquement. Ce document explique comment concevoir des workflows transactionnels à l'aide de Cloud Run, Pub/Sub, Workflows et Firestore en mode Datastore (Datastore). Il est destiné aux développeurs d'applications qui souhaitent concevoir des workflows transactionnels dans une application basée sur des microservices.
Ce document fait partie d'une série composée des parties suivantes :
- Workflows transactionnels dans une architecture de microservices sur Google Cloud (ce document).
- Déployer un exemple d'application de workflows transactionnels dans une architecture de microservices : il s'agit d'un tutoriel qui explique comment déployer et utiliser un exemple d'application utilisant l'architecture décrite dans ce document.
Transactions de bout en bout dans des microservices
Dans les architectures de microservices, une transaction de bout en bout peut couvrir plusieurs services. Chaque service peut offrir une fonctionnalité spécifique et sa propre base de données indépendante, comme illustré dans le schéma suivant.
Comme le montre l'image précédente, un client accède à plusieurs microservices via une passerelle. En raison de ce type d'accès client, vous ne pouvez pas compter sur les fonctionnalités transactionnelles d'une seule base de données pour aider votre système de base de données à récupérer des pannes et à garantir la cohérence. À la place, nous vous recommandons de mettre en œuvre un workflow transactionnel dans votre architecture de microservices.
Ce document décrit deux modèles que vous pouvez utiliser pour mettre en œuvre un workflow transactionnel dans une architecture de microservices. Les modèles sont les suivants :
- Modèle Saga basé sur la chorégraphie
- Modèle d'orchestration synchrone
Exemple d'application
Pour illustrer le workflow, ce document utilise un exemple simple d'application qui peut gérer les transactions de commande d'un site Web d'achat. L'application gère les clients et les commandes. Les clients ont une limite de crédit, et l'application doit confirmer qu'une nouvelle commande ne dépassera pas la limite de crédit du client. Comme le montre le schéma suivant, le workflow transactionnel s'exécute sur les microservices suivants : le service Order
et le service Customer
.
Le workflow se déroule comme suit :
- Un client envoie une requête de commande qui spécifie un ID client et un certain nombre d'articles.
- Le service
Order
attribue un ID de commande et stocke les informations de la commande dans la base de données. L'état de la commande est marqué commepending
. - Le service
Customer
augmente l'utilisation du crédit du client qui est stockée dans la base de données en fonction du nombre d'articles commandés (par exemple, une augmentation de 100 crédits pour un seul article). - Si l'utilisation totale du crédit est inférieure ou égale à la limite prédéfinie, la commande est acceptée et le service
Order
fait passer àaccepted
l'état de la commande dans la base de données. - Si l'utilisation totale du crédit est supérieure à la limite prédéfinie, le service
Order
remplace l'état de la commande parrejected
. Dans ce cas, l'utilisation du crédit n'est pas augmentée.
Description du service "Order"
Le service Order
gère l'état d'une commande. Il génère et stocke un enregistrement de commande dans la base de données Order
pour chaque requête client. L'enregistrement comprend les colonnes suivantes :
Order_id
: ID de la commande. Cet ID est généré par le serviceOrder
.Customer_id
: ID client.Number
: quantité d'articles dans la commande.Status
: état d'une commande.
Description du service "Customer"
Le service Customer
gère les crédits client. Il génère et stocke un enregistrement client dans la base de données Customer
pour chaque requête client. L'enregistrement comprend les colonnes suivantes :
Customer_id
: ID du client, qui est généré par le serviceCustomer
.Credit
: nombre de crédits consommés par le client. Il augmente lorsque le client commande des articles.Limit
: limite de crédit individuelle du client. Une commande est refusée lorsque le crédit du client dépasse la limite définie.
Modèle Saga basé sur la chorégraphie
Cette section explique comment mettre en œuvre un modèle de microservices Saga basé sur la chorégraphie dans un workflow transactionnel.
Présentation de l'architecture
Dans un modèle de microservices Saga basé sur la chorégraphie, les microservices fonctionnent comme un système autonome distribué. Lorsqu'un service modifie l'état de sa propre entité, il publie un événement pour en informer les autres services des mises à jour. L'événement de notification déclenche l'action d'autres services. De cette manière, plusieurs services fonctionnent conjointement pour mener à bien un processus transactionnel. La communication entre les microservices est asynchrone. Lorsqu'un service publie un événement, aucune information n'est envoyée au service de publication pour confirmer les services qui reçoivent l'événement ni quand ils le reçoivent.
L'image suivante montre un exemple de modèle de microservices Saga basé sur la chorégraphie.
L'exemple d'architecture présenté dans l'image précédente est le suivant :
- Cloud Run agit comme un environnement d'exécution de microservices.
- Pub/Sub agit comme un service de messagerie pour diffuser des événements entre les microservices.
- Datastore fournit une base de données pour chaque service.
Datastore permet de stocker des événements avant de les publier. Comme expliqué dans le processus de publication d'événements, les microservices stockent les événements au lieu de les publier immédiatement.
Les services Order
et Customer
stockent d'abord les événements dans la base de données d'événements.
Les événements stockés sont ensuite publiés régulièrement à l'aide de Cloud Scheduler.
Cloud Scheduler appelle le service event-publisher
, qui publie les événements. Ce flux d'événements est illustré dans l'image suivante :
Workflow transactionnel
Dans un workflow transactionnel, deux services communiquent entre eux via des événements. Dans cette architecture, la commande du client est traitée comme suit :
- Le client envoie une requête de commande qui spécifie l'ID du client et le nombre d'articles qu'il a commandés. La requête est envoyée au service
Order
via une API REST. - Le service
Order
attribue un ID à la commande et stocke les informations sur celle-ci dans la base de donnéesOrder
. L'état de la commande est marqué commepending
. Le serviceOrder
renvoie les informations de la commande au client et publie un événement qui les inclut dans le sujet Pub/Sub suivant :order-service-event
. - Le service
Customer
reçoit l'événement via une notification push. Elle augmente l'utilisation du crédit du client, qui est stockée dans la base de donnéesCustomer
en fonction du nombre d'articles commandés. - Si l'utilisation totale du crédit est inférieure ou égale à la limite prédéfinie, le service
Customer
publie un événement indiquant que l'augmentation du crédit a réussi. Dans le cas contraire, il publie un événement indiquant que l'augmentation du crédit a échoué. Dans ce cas, l'utilisation du crédit n'est pas augmentée. - Le service
Order
reçoit l'événement via une notification push. Il remplace l'état de la commande paraccepted
ourejected
selon le cas. Le client peut suivre l'état de la commande à l'aide de l'ID de commande renvoyé par le serviceOrder
.
Le schéma suivant synthétise ce workflow :
Processus de publication des événements
Lorsqu'un microservice modifie ses propres données dans la base de données et publie un événement pour avertir la base de données, ces deux opérations doivent être effectuées de manière atomique. Par exemple, si le microservice échoue après qu'il a modifié des données sans publier d'événement, le processus transactionnel s'arrête. Dans ce cas, les données peuvent être laissées dans un état incohérent entre les différents microservices impliqués dans la transaction. Pour éviter ce problème, dans l'exemple d'application utilisé dans ce document, les microservices écrivent des données d'événement dans la base de données backend au lieu de publier directement les événements dans Pub/Sub.
Les données sont modifiées et les données d'événement associées sont écrites de manière atomique, à l'aide de la fonctionnalité transactionnelle de la base de données backend. Ce modèle, illustré dans l'image suivante, est couramment appelé "événements d'application" ou "boîte d'envoi transactionnelle".
Comme indiqué dans l'image précédente, la colonne published
des données d'événement est initialement marquée comme False
. Ensuite, le service event-publisher
analyse régulièrement la base de données et publie les événements dont la colonne published
contient la valeur False
.
Une fois l'événement publié, le service event-publisher
remplace la valeur de la colonne published
par True
.
Comme le montre l'image suivante, la base de données Order
et la base de données Event
d'un même espace de noms peuvent être mises à jour de manière atomique par des transactions Datastore.
Si le service event-publisher
échoue après la publication d'un événement sans modifier la colonne published
, il publie à nouveau le même événement après sa récupération. Étant donné que la nouvelle publication de l'événement entraîne un événement en double, les microservices qui reçoivent l'événement doivent rechercher des doublons potentiels et les gérer en conséquence. Cette approche permet de garantir l'idempotence de la gestion des événements.
L'image suivante montre comment un exemple d'application traite la duplication d'événements.
Comme illustré dans le schéma précédent, l'application gère les événements en double avec le workflow suivant :
- Chaque microservice met à jour sa base de données backend correspondante en fonction de la logique métier déclenchée par un événement, et écrit l'ID d'événement dans sa base de données.
- Ces deux écritures sont effectuées de manière atomique à l'aide de la fonctionnalité transactionnelle utilisée par les bases de données backend.
- Si les services reçoivent un événement en double, celui-ci est détecté lorsque les services recherchent l'ID d'événement dans leurs bases de données.
La gestion des événements en double est une pratique courante lors de la réception d'événements depuis Pub/Sub, car il y a une petite chance que Pub/Sub entraîne la diffusion de messages en double.
Développer l'architecture
Dans l'exemple d'application, avant de traiter un message, vous pouvez utiliser Datastore pour vérifier s'il est dupliqué. Cette approche signifie que le service qui utilise les messages (le service Customer
, dans ce cas) est idempotent. Cette approche est généralement appelée "modèle consommateur idempotent". Certains frameworks mettent en œuvre ce modèle en tant que fonctionnalité intégrée, par exemple Eventuate.
Cependant, l'accès à la base de données à chaque fois que vous traitez un message peut entraîner des problèmes de performances. Une solution consiste à utiliser une base de données offrant de bonnes performances et une bonne évolutivité, par exemple Redis.
Modèle d'orchestration synchrone
Cette section explique comment mettre en œuvre un modèle de microservices d'orchestration synchrone dans un workflow transactionnel.
Présentation de l'architecture
Dans ce modèle, un seul orchestrateur contrôle le flux d'exécution d'une transaction. La communication entre les microservices et l'orchestrateur s'effectue de manière synchrone via des API REST.
Dans l'exemple d'architecture décrit dans ce document, Cloud Run est utilisé comme environnement d'exécution de microservices et Datastore comme base de données backend pour chaque service. En outre, Workflows est utilisé en tant qu'orchestrateur. Ce schéma est illustré dans l'image suivante :
Workflow transactionnel
Dans l'architecture d'un workflow synchrone, la commande d'un client est traitée comme suit :
- Le client envoie une requête de commande qui spécifie l'ID d'un client et le nombre d'articles qu'il a commandés. La requête est envoyée au service
Order processor
via l'API REST. - Le service
Order processor
exécute un workflow dans lequel l'ID client et le nombre d'articles sont transmis à Workflows. - Le workflow appelle l'API REST du service
Order
et transmet l'ID client et le nombre d'articles commandés par le client. Ensuite, le serviceOrder
attribue un ID de commande à la commande du client et stocke les informations concernant celle-ci dans la base de donnéesOrder
. L'état de la commande est marqué commepending
. Le serviceOrder
renvoie les informations de la commande au workflow. - Le workflow appelle l'API REST du service
Customer
et transmet l'ID client et le nombre d'articles commandés par le client. Ensuite, le serviceCustomer
augmente l'utilisation du crédit du client qui est stockée dans la base de donnéesCustomer
en fonction du nombre d'articles commandés. - Si l'utilisation totale du crédit est inférieure ou égale à la limite prédéfinie, le service
Customer
renvoie des données expliquant que l'augmentation du crédit a réussi. Dans le cas contraire, il renvoie des données expliquant que l'augmentation du crédit a échoué. Dans ce cas, l'utilisation du crédit n'est pas augmentée. - Le workflow appelle l'API REST du service
Order
pour remplacer l'état de la commande paraccepted
ourejected
, selon le cas. Enfin, il renvoie les informations sur la commande dans la mise à jour de l'état final au serviceOrder processor
. Ensuite, le serviceOrder processor
renvoie ces informations au client.
Ce workflow est résumé dans le diagramme suivant :
Avantages et inconvénients
Lorsque vous envisagez de mettre en œuvre un modèle Saga basé sur la chorégraphie ou un modèle d'orchestration synchrone, le meilleur choix pour votre organisation est toujours le modèle le plus adapté à ses besoins. Toutefois, en général, en raison de sa simplicité de conception, l'orchestration synchrone est souvent le premier choix pour de nombreuses entreprises.
Le tableau suivant récapitule les avantages et les inconvénients du modèle Saga basé sur la chorégraphie et du modèle d'orchestration synchrone décrits dans ce document.
Avantages |
Inconvénients |
|
---|---|---|
Saga basé sur la chorégraphie |
Couplage faible : chaque service publie des événements dans Datastore en cas de modification de ses propres données. Aucune information n'est envoyée à d'autres services. Cette approche rend chaque service plus indépendant, et réduit le risque d'avoir besoin de modifier les services lorsque vous ajoutez de nouveaux services au workflow. |
Dépendance complexe : la mise en œuvre de l'intégralité du workflow est répartie entre les services. Par conséquent, il peut être difficile de comprendre le workflow. Cette approche pourrait introduire accidentellement une complexité dans les modifications de conception et le dépannage futurs. |
Orchestration synchrone |
Dépendance simple : un seul orchestrateur contrôle l'intégralité du flux d'exécution d'une transaction. Il est ainsi plus facile de comprendre le fonctionnement du flux de transactions. Ce modèle simplifie la modification du workflow et le dépannage. |
Risque de couplage fort : l'orchestrateur central dépend de tous les services qui composent le workflow transactionnel. Par conséquent, lorsque vous modifiez l'un de ces services ou ajoutez de nouveaux services au workflow, vous devrez peut-être modifier l'orchestrateur en conséquence. Cet effort supplémentaire peut surpasser l'avantage de pouvoir modifier et ajouter des services plus indépendamment de l'architecture de microservices par rapport aux systèmes monolithiques. |
Étapes suivantes
- Apprenez-en plus sur les architectures de microservices.
- Découvrez des architectures de référence, des schémas et des bonnes pratiques concernant Google Cloud. Consultez notre Centre d'architecture cloud.