J'ai récemment lu cet excellent article sur l'architecture de microservice: http://www.infoq.com/articles/microservices-intro
Il indique que lorsque vous chargez une page Web sur Amazon, plus de 100 microservices coopèrent pour servir cette page.
Cet article explique que toutes les communications entre microservices ne peuvent passer que par une API. Ma question est la suivante: pourquoi est-il si grave de dire que toutes les écritures de base de données ne peuvent passer que par une API, mais que vous êtes libre de lire directement à partir des bases de données des différents micro-services. On pourrait par exemple dire que seules quelques vues de base de données sont accessibles en dehors du micro service afin que l'équipe de maintenance du micro service sache que, tant qu'elles conservent ces vues intactes, elles peuvent modifier autant que possible la structure de la base de données de leur micro service. vouloir.
Est-ce que j'ai râté quelque chose? Existe-t-il une autre raison pour laquelle les données ne devraient être lues que via une API?
Inutile de dire que mon entreprise est nettement plus petite qu'Amazon (et le sera toujours) et que nous pouvons avoir un nombre maximal d'utilisateurs de 5 millions.
Réponses:
Les bases de données ne sont pas très douées pour cacher des informations, ce qui est tout à fait plausible, car leur travail consiste à exposer des informations. Mais cela les rend un outil moche en matière d'encapsulation. Pourquoi voulez-vous une encapsulation?
Scénario: vous liez directement quelques composants à un SGBDR et vous voyez un composant en particulier devenir un goulot de performance pour lequel vous souhaiterez peut-être dénormaliser la base de données, mais vous ne pourrez pas, car tous les autres composants seraient affectés. Vous pouvez même réaliser que vous seriez mieux avec un magasin de documents ou une base de données de graphes qu'avec un SGBDR. Si les données sont encapsulées par une petite API, vous avez une chance réaliste de réimplémenter ladite API comme vous le souhaitez. Vous pouvez insérer des couches de cache de manière transparente et non.
La couche de stockage directement à partir de la couche d’application est l’opposé diamétralement opposé de ce que suggère le principe d’inversion de dépendance .
la source
Qu'y a-t-il de plus important et de significatif dans un microservice: son API ou son schéma de base de données? L'API, car c'est son contrat avec le reste du monde. Le schéma de base de données est simplement un moyen pratique de stocker les données gérées par le service, organisées de manière à optimiser les performances de microservice. L'équipe de développement doit être libre de réorganiser ce schéma - ou de passer à une solution de banque de données totalement différente - à tout moment. Le reste du monde ne devrait pas s'en soucier. Le reste du monde se soucie du changement d’API, car c’est le contrat.
Maintenant, si vous allez jeter un coup d'œil dans leur base de données
Les deux derniers points peuvent ne pas se produire si vous n’avez qu’un accès en lecture, mais les autres points sont plus qu’une raison suffisante. Les bases de données partagées sont une mauvaise chose.
Il est courant que les développeurs moins expérimentés (ou ceux qui n’apprennent pas) considèrent que la base de données est plus importante que le service, que la base de données est réelle et que le service n’est qu’un moyen d’y accéder. C'est le mauvais sens.
la source
Il est difficile de décrire l’architecture des microservices, mais la meilleure façon d’y penser est de faire un mariage entre l’architecture orientée composants et l’architecture orientée services. Le logiciel en tant que suite est composé de nombreux composants de petite entreprise avec une responsabilité très spécifique du domaine. Leur interface avec le monde extérieur, que ce soit dans les services fournis ou les services requis, se fait via une API de services clairement définis.
Écrire et même lire à partir d'une base de données en dehors du domaine métier de vos composants va à l'encontre de ce style d'architecture.
La principale raison à cela est qu'une API fournie via un service par un autre composant logiciel via un service peut raisonnablement s'attendre à ce qu'elle soit rétrocompatible à mesure que de nouvelles versions du composant fournissant le service deviennent disponibles. Si je suis le développeur d'un composant "fournissant", je n'ai plus qu'à m'inquiéter de la compatibilité ascendante de mon API. Si je sais que trois autres équipes de développement ont écrit directement des requêtes personnalisées sur ma base de données, mon travail est devenu beaucoup plus compliqué.
Pire encore, peut-être que cette autre équipe qui a écrit ceci est à mi-sprint dans un projet critique et ne peut pas accepter ce changement maintenant de votre composant. Désormais, le développement logiciel pour votre composant sur un domaine professionnel que vous possédez est guidé par le développement sur un autre domaine commercial.
Une interaction complète par le biais des services réduit le couplage entre divers composants logiciels, de sorte que de telles situations ne se produisent pas aussi souvent. En ce qui concerne les autres composants utilisant une vue dans la base de données, vous avez davantage de possibilités pour la rendre rétro-compatible si quelqu'un d'autre a écrit des requêtes à ce sujet. Je pense néanmoins que cela devrait être un cas exceptionnel et ne devrait être fait que pour les rapports ou le traitement par lots, où une application doit lire des quantités énormes de données.
Il est clair que cela fonctionne bien dans les grandes équipes distribuées où les équipes de développement sont séparées par domaine métier comme Amazon. Si vous êtes un petit magasin de développement, vous pouvez toujours bénéficier de ce modèle, en particulier si vous devez vous lancer rapidement dans un projet de grande envergure, mais également si vous devez utiliser des logiciels de fournisseurs.
la source
Au cours des 20 dernières années, j'ai vu quelques grandes conceptions de base de données modulaires et j'ai vu le scénario suggéré par David à plusieurs reprises, où les applications ont un accès en écriture à leur propre schéma / jeu de tables et un accès en lecture à un autre schéma / ensemble de tables. Le plus souvent, les données auxquelles une application / module obtient un accès en lecture seule peuvent être qualifiées de "données de base" .
À l'époque, je n'avais pas vu les problèmes que les réponses précédentes suggéraient que j'aurais dû voir. Je pense qu'il est donc utile d'examiner de plus près les points soulevés dans les réponses précédentes de manière plus détaillée.
Je suis d'accord avec ce commentaire, sauf que c'est également un argument en faveur d'une copie locale des données pour que le microservice puisse être lu. C'est-à-dire que la plupart des bases de données matures prennent en charge la réplication . Ainsi, sans aucun effort de développement, les "données de base" peuvent être physiquement répliquées dans la base de données microservice si cela est souhaité ou nécessaire.
Certains pourraient reconnaître cela sous une apparence plus ancienne en tant que "base de données d'entreprise" répliquant les tables principales vers une "base de données ministérielle". Un point ici est qu’il est généralement bon qu’une base de données le fasse pour nous avec une réplication intégrée des données modifiées (uniquement les deltas, sous forme binaire et à un coût minimal pour la base de données source).
À l'inverse, lorsque nos choix de base de données n'autorisent pas cette prise en charge de la réplication "standard", nous pouvons nous retrouver dans une situation dans laquelle nous voulons transférer les "données principales" vers les bases de données de microservice, ce qui peut entraîner d'importants efforts de développement et également être un mécanisme sensiblement moins efficace.
Pour moi, cette affirmation n’est tout simplement pas correcte. La dénormalisation est un changement "additif" et non pas un "changement radical" et aucune application ne devrait être interrompue en raison d'une dénormalisation.
La seule façon pour cette interruption d'une application est lorsque le code d'application utilise quelque chose comme "select * ..." et ne gère pas une colonne supplémentaire. Pour moi, ce serait un bug dans l'application?
Comment la dénormalisation peut-elle interrompre une application? Cela ressemble à du fud pour moi.
Oui, l'application dépend maintenant du schéma de la base de données, ce qui implique un problème majeur. Bien que l'ajout de toute dépendance supplémentaire ne soit évidemment pas idéal, mon expérience est que la dépendance au schéma de base de données n'a pas posé de problème, alors pourquoi cela pourrait-il être le cas? Est-ce que je viens d'avoir de la chance?
Données de base
Le schéma auquel nous souhaitons généralement qu'un microservice ait un accès en lecture seule est le plus souvent ce que je qualifierais de " données de base " pour l'entreprise. Il contient les données essentielles essentielles à l'entreprise.
Historiquement, cela signifie que le schéma auquel nous ajoutons la dépendance est à la fois mature et stable (assez fondamental pour l’entreprise et immuable).
Normalisation
Si 3 concepteurs de base de données conçoivent un schéma de base de données normalisé, ils se retrouveront dans la même conception. Ok, il pourrait y avoir quelques variations 4NF / 5NF mais pas beaucoup. De plus, le concepteur peut poser toute une série de questions pour valider le modèle, afin de pouvoir être sûr qu'il est arrivé à 4NF (suis-je trop optimiste? Les gens ont-ils du mal à atteindre 4NF?).
update: par 4NF , je veux dire que toutes les tables du schéma ont atteint leur forme normale la plus élevée jusqu'à 4NF (toutes les tables ont été normalisées de manière appropriée jusqu'à 4NF).
Je crois que le processus de conception de la normalisation est la raison pour laquelle les concepteurs de bases de données sont généralement à l'aise avec l'idée de dépendre d'un schéma de base de données normalisé.
Le processus de normalisation donne à la conception de base de données une conception "correcte" connue et les variations à partir de là doivent être dénormalisées pour améliorer les performances.
Si 3 concepteurs avaient une conception à implémenter (sous forme de code), on s'attendrait à 3 implémentations différentes (potentiellement très différentes).
Pour moi, il y a potentiellement une question de "foi en la normalisation".
Briser les changements de schéma?
La dénormalisation, l’ajout de colonnes, la modification de colonnes pour un stockage plus important, l’extension de la conception avec de nouvelles tables, etc. constituent des modifications inébranlables.
Les changements de rupture sont évidemment possibles en supprimant des colonnes / des tableaux ou en effectuant un changement de type de rupture. Oui, mais concrètement, je n’ai rencontré aucun problème ici. Peut-être parce que l'on comprend ce que sont les changements de rupture et que ceux-ci ont été bien gérés?
Je serais intéressé d'entendre des cas de changements de schéma brisés dans le contexte de schémas partagés en lecture seule.
Bien que je sois d’accord avec cette affirmation, j’estime qu’un architecte de l’entreprise pourrait nous avertir du fait que «les données durent éternellement» . En d’autres termes, bien que l’API soit l’aspect le plus important, les données sont également très importantes pour l’entreprise dans son ensemble et le resteront pendant très longtemps.
Par exemple, une fois que vous avez besoin de renseigner Data Warehouse for Business Intelligence, le schéma et la prise en charge de CDC deviennent importants du point de vue des rapports commerciaux, quelle que soit l'API.
Des problèmes avec les API?
Maintenant, si les API étaient parfaites et faciles, tous les points sont sans objet puisque nous choisirions toujours une API plutôt que d'avoir un accès local en lecture seule. Ainsi, même en considérant l'accès local en lecture seule, il est possible que l'API évite certains problèmes d'utilisation des API.
Optimisation de l'API:
LinkedIn a une présentation intéressante (à partir de 2009) sur la question de l'optimisation de leur API et pourquoi c'est important pour eux à leur échelle. http://www.slideshare.net/linkedin/building-consistent-restful-apis-in-a-highperformance-environment
En bref, une fois qu'une API doit prendre en charge de nombreux cas d'utilisation différents, elle peut facilement se retrouver dans une situation où elle prend en charge un cas d'utilisation de manière optimale et le reste plutôt mal du point de vue du réseau et de la base de données.
Si l'API n'a pas la même sophistication que LinkedIn, vous pouvez facilement obtenir les scénarios suivants:
Oui, nous pouvons bien sûr ajouter la mise en cache aux API, mais au bout du compte, l'appel de l'API est un appel à distance et une série d'optimisations est disponible pour les développeurs lorsque les données sont locales.
Je soupçonne qu'il y a un ensemble de personnes qui pourraient l'additionner comme:
Cette réponse est trop longue. Excuses !!
la source
La gestion des états (potentiellement une base de données) peut être déployée dans le conteneur de Microservice et exposée via une API. La base de données d'un Microservice n'est pas visible par les autres systèmes en dehors du conteneur - uniquement par l'API. Vous pouvez également faire appel à un autre service (un cache, par exemple) pour gérer l'état via une API. Le fait de disposer de toutes les dépendances de Microservice (autres que les appels d'API vers d'autres services) au sein d'un même conteneur déployable est une distinction clé de l'architecture. Si on ne l'obtient pas, retournez et étudiez l'architecture.
la source