J'ai du mal à éviter la duplication des données ou une base de données partagée, même pour la conception de microservices la plus simple, ce qui me fait penser que je manque quelque chose. Voici un exemple de base du problème auquel je suis confronté. En supposant que quelqu'un utilise une application Web pour gérer un inventaire, il aurait besoin de deux services; un pour l'inventaire gérant les articles et la quantité en stock et un service utilisateurs qui gérerait les données utilisateurs. Si nous voulons un audit de qui a stocké la base de données, nous pouvons ajouter l'ID utilisateur à la base de données pour le service d'inventaire en tant que dernier stocké par valeur.
En utilisant l'application, nous pouvons vouloir voir tous les articles qui manquent et une liste de ceux qui les ont stockés la dernière fois afin que nous puissions leur demander de le réapprovisionner. En utilisant l'architecture décrite ci-dessus, une demande serait effectuée auprès du service d'inventaire pour récupérer les détails de tous les articles dont la quantité est inférieure à 5. Cela retournerait une liste comprenant les ID utilisateur. Ensuite, une demande distincte serait faite au service des utilisateurs pour obtenir le nom d'utilisateur et les coordonnées de la liste des ID utilisateur obtenus auprès du service d'inventaire.
Cela semble terriblement inefficace et il ne faut pas beaucoup plus de services avant de faire plusieurs demandes à différentes API de services qui à leur tour effectuent plusieurs requêtes de base de données. Une alternative consiste à répliquer les détails des utilisateurs dans les données d'inventaire. Lorsqu'un utilisateur modifie ses coordonnées, nous devons alors reproduire la modification via tous les autres services. Mais cela ne semble pas correspondre à l'idée de contexte borné des microservices. Nous pourrions également utiliser une seule base de données et la partager entre différents services, et avoir tous les problèmes d'une base de données d'intégration .
Quelle est la bonne / meilleure façon de mettre cela en œuvre?
la source
Réponses:
J'ai complètement raté l'endroit où vous devez dupliquer.
Un principe central des microservices est que le service soit la seule autorité. Cela signifie que la gestion des stocks et des utilisateurs peut être complètement séparée. Je concevrais la gestion des utilisateurs de manière à ce qu'il ne sache même pas que le système d'inventaire existe.
Mais je conçois le système d'inventaire de sorte qu'il ne stocke jamais rien sur les utilisateurs autre qu'un ID utilisateur. Cela résout votre problème de propagation des modifications des informations utilisateur.
Quant aux choses qui nécessitent à la fois des informations d'inventaire et des informations utilisateur telles que les journaux, les audits et les impressions, elles ne sont pas mises à jour lorsque les informations changent. Ils sont un enregistrement de ce qui était. Encore une fois, vous ne propagez pas le changement.
Donc, dans tous les cas, lorsque vous voulez les dernières informations utilisateur, vous demandez au service d'informations utilisateur.
la source
It seems counter-intuitive to move from a single relational database where I could get the inventory data and the user data with a join
Gardez à l'esprit que «idéalement», il y a un magasin par service (ou plus!). Il n'y a donc rien de tel que la «jonction» entre les «frontières». La raison est simple, DB génère un couplage entre services. Contrairement à @CandiedOrange, je pense que nous pouvons dupliquer un minimum de données d'un service à un autre. Je fais référence à des données qui ne changeront probablement pas. Si ces doublons améliorent l'efficacité et les performances (et les deux sont requis), les "avantages" compenseraient probablement les "inconvénients"Selon l' ebook de Microsoft sur l'architecture des microservices , il n'y a rien de mal à la duplication des données. Fondamentalement, la duplication des données augmente le découplage entre les services et renforce donc leurs rôles en tant qu'autorité unique. Un passage pertinent:
la source
Oui en effet.
Certes, dans un monolithe, vous pourriez avoir un modèle d'inventaire que vous recherchez pour les éléments pertinents, l'injecter dans un modèle utilisateur et obtenir les mêmes données.
Ou vous pouvez aller plus loin, si vous les avez dans la même base de données relationnelle et que vous écrivez SQL et que la base de données prendra la table d'inventaire et la table d'utilisateur, cela fait un peu de magie et vous obtenez les données que vous recherchez.
Quelle que soit la façon dont vous le faites, il y aura quelque part du code qui récupérera essentiellement une liste des identifiants utilisateur du système d'inventaire, les alimentera dans le système utilisateur et compilera une liste de données.
La question à laquelle vous devez répondre concerne les performances et la maintenance et les autres qualités "douces".
Le principal avantage des microservices est la mise à l'échelle. Si vous avez dix mille utilisateurs sur une machine et que c'est un peu lent, vous pouvez ajouter une autre machine et le système devient deux fois plus rapide. Ajoutez-en huit de plus et c'est dix fois plus rapide. (Mise à l' échelle linéaire est probablement optimiste, mais il est l'idéal et non que déraisonnable d'espérer.)
Et c'est par service . Si le système d'inventaire est le goulot d'étranglement, il est utilisé pour plus que des rapports sur les utilisateurs, vous pouvez ajouter plus de machines à ce service uniquement . Les machines peuvent également être spécialisées; ce service a besoin de beaucoup de mémoire, ce service fait des calculs lourds et a besoin de plus de cpu.
Si vous n'avez pas besoin de la mise à l'échelle, il y a un autre avantage des microservices: ils sont modulaires . Bien sûr, les applications monolithiques peuvent également être modulaires, et vous avez une base de données normalisée et ... mais dans la pratique, les murs entre les modules sont comme des murs en verre dans le meilleur des cas, et des lignes dans le sable dans le pire. Les microservices sont séparés par de l'acier massif.
Si votre système utilisateur prend littéralement feu, cela n'affectera en rien votre système d'inventaire. Vous ne pourrez pas imprimer de jolis rapports sur qui a stocké quoi, mais les clients pourront passer des commandes en toute sécurité en sachant que les articles en stock sont là.
Et vous ne dupliquez pas les données dans les microservices , pas plus que dans une base de données relationnelle (*). Dans une base de données relationnelle, vous pouvez faire une jointure , et l'équivalent est de fusionner les listes en code comme décrit.
Vous pouvez également ajouter une vue , l'équivalent est d'ajouter un nouveau service qui fait la fusion pour vous; cela aboutirait à trois demandes; un au nouveau service, puis ce service fait les deux d'origine. Les bases de données relationnelles ont des éléments sophistiqués qui optimisent les vues, qui doivent être implémentées au niveau du service. Vous ne l'obtenez pas "gratuitement".
La mise en cache est différente de la duplication de données en ce sens que si deux valeurs ne correspondent pas, vous savez laquelle est fausse. Il est souvent utilisé dans les microservices pour augmenter la disponibilité au détriment de la cohérence (théorème CAP). Étant donné que les bases de données relationnelles suppriment complètement la disponibilité sur l'autel de la cohérence, elles y sont moins courantes. Je dirais qu'il n'y a rien d'inhérent aux microservices qui facilite la mise en cache, mais dans la pratique, la mise en cache est une préoccupation principale et qui facilite la mise en cache dans les microservices .
(*) S'il est logique de dupliquer des données dans un essaim de microservices, cela aurait probablement du sens dans la base de données relationnelle équivalente à.
la source