Est-ce une mauvaise pratique pour les services de partager une base de données dans SOA?

17

J'ai récemment lu les modèles d'intégration d'entreprise de Hohpe et Woolf, certains des livres de Thomas Erl sur SOA et regardé diverses vidéos et podcasts par Udi Dahan et al. sur les systèmes CQRS et Event Driven.

Les systèmes sur mon lieu de travail souffrent d'un couplage élevé. Bien que chaque système ait théoriquement sa propre base de données, il y a beaucoup de jonction entre eux. En pratique, cela signifie qu'il existe une énorme base de données que tous les systèmes utilisent. Par exemple, il existe une table de données client.

Une grande partie de ce que j'ai lu semble suggérer de dénormaliser les données afin que chaque système utilise uniquement sa base de données, et toutes les mises à jour d'un système sont propagées à tous les autres à l'aide de la messagerie.

Je pensais que c'était l'un des moyens de faire respecter les limites dans SOA - chaque service devrait avoir sa propre base de données, mais j'ai lu ceci:

/programming/4019902/soa-joining-data-across-multiple-services

et cela suggère que ce n'est pas la bonne chose à faire.

La ségrégation des bases de données semble être un bon moyen de découpler les systèmes, mais maintenant je suis un peu confus. Est-ce une bonne voie à suivre? Est-il jamais recommandé de séparer une base de données, par exemple un service SOA, un contexte DDD Bounded, une application, etc.?

Paul T Davies
la source
La question d'origine que vous liez est incorrecte. La question elle-même est fausse, comme la plupart des réponses y échappent. SOA ne consiste pas à diviser une seule application en services discrets et à partitionner leurs données.
Jeremy
Je comprends que la question est fausse, ce sont les réponses qui m'ont fait réévaluer ma pensée.
Paul T Davies
Je pense que les services doivent être couplés
B Seven

Réponses:

12

Le découplage ne fonctionne que s'il y a vraiment une séparation. Considérez si vous avez un système de commande:

  • Tableau: CLIENT
  • Tableau: COMMANDE

Si c'est tout ce que vous avez, il n'y a aucune raison de les dissocier. D'un autre côté, si vous avez ceci:

  • Tableau: CLIENT
  • Tableau: COMMANDE
  • Tableau: CUSTOMER_NEWSLETTER

Vous pourriez alors affirmer que ORDER et CUSTOMER_NEWSLETTER font partie de deux modules totalement distincts (commande et marketing). Il est peut-être judicieux de les déplacer dans des bases de données distinctes (une pour chaque table) et de faire en sorte que les deux modules partagent l'accès à la table CUSTOMER commune dans sa propre base de données.

En faisant cela, vous simplifiez chaque module, mais vous augmentez la complexité de votre couche de données. À mesure que votre application devient de plus en plus grande, je peux voir un avantage à la séparation. Il y aura de plus en plus d '"îlots de données" qui n'ont vraiment aucun rapport les uns avec les autres. Cependant, il y aura toujours des données qui recoupent tous les modules.

La décision de les placer dans différentes bases de données physiques serait généralement basée sur des contraintes du monde réel telles que la fréquence des sauvegardes, les restrictions de sécurité, la réplication vers différents emplacements géographiques, etc. Je ne séparerais pas les tables en différentes bases de données physiques simplement en raison de la séparation des préoccupations. Cela peut être géré plus simplement avec différents schémas ou vues.

Scott Whitlock
la source
5
-1. Ils ne devraient être dans des bases de données séparées que s'il y a une raison de les y mettre. Vous devez «en tirer quelque chose», car cela rend certainement votre application plus complexe.
scottschulthess
1
Je pense qu'il vaut la peine de mettre l'accent sur l'importance de séparer les deux domaines de fonctionnalité au niveau de la couche de données (que ce soit en utilisant des schémas séparés ou autre chose). Chaque module doit uniquement accéder aux données de l'autre module via l'API de l'autre module - cela est similaire aux principes OO d'encapsulation. C'est à dire ne pas partager un schéma entre plusieurs modules. Aussi, je déconseille les vues, préférant plutôt exposer les données via. une API.
Chris Snow
@scottschulthess oui, vous devez peser le coût de la complexité et si cela n'en vaut pas la peine, vous ne pouvez tout simplement pas vous diviser en services. Fractionner mais en utilisant une base de données partagée que j'ai trouvée est la pire des 3 options.
Adamantish
8

Là où je travaille, nous avons un ESBauquel 6 applications différentes (ou devrais-je dire "points d'extrémité") sont connectées. Ces 6 applications fonctionnent avec 3 schémas Oracle différents sur 2 instances de base de données. Certaines de ces applications coexistent dans le même schéma non pas parce qu'elles sont liées mais parce que notre infrastructure de base de données est gérée par un fournisseur externe et obtenir un nouveau schéma prend juste une éternité (aussi, nous n'avons pas d'accès DBA bien sûr) ... prend vraiment tellement de temps qu'à un moment donné, nous avons pensé à réutiliser un schéma existant "temporairement" pour pouvoir continuer le développement. Pour appliquer la "séparation" des données, les noms de table sont préfixés, par exemple "CST_" pour le client. De plus, nous devons travailler avec un schéma qui, pour des raisons valables, nous ne pouvons pas changer complètement ... C'est étrange, je sais. Bien sûr, comme cela arrive toujours, "temporairement"

Nos différentes applications se connectent à leur schéma de base de données respectif et fonctionnent avec leurs propres packages PL / SQL et nous nous interdisons absolument d'interagir directement avec des tables / données qui sont en dehors de notre domaine d'application.

Lorsqu'une des applications connectées à l'ESB a besoin d'informations en dehors de son domaine, elle appelle le service associé sur l'ESB pour obtenir les données, même si ces informations sont en fait dans le même schéma, ne nécessitant en théorie qu'une petite instruction join dans l'une des requêtes SQL .

Nous le faisons afin de pouvoir diviser notre domaine d'application en différents schémas / bases de données, et pour que les services sur l'ESB fonctionnent toujours correctement quand cela se produit (c'est bientôt Noël, nous corsons les doigts)

Maintenant, cela peut sembler étrange et horrible de l'extérieur, mais il y a des raisons à cela et je voulais juste partager cette expérience concrète pour vous montrer qu'une ou plusieurs bases de données ne sont pas si importantes. Attends, ça l'est!, pour de nombreuses raisons (+1 pour Scott Whitlock, voir le dernier paragraphe sur la sauvegarde et tel que mya vous amène à des ennuis) Mais il est tout aussi important, je pense, d'avoir vos services SOA correctement conçus, du moins c'est mon avis, et je ne suis pas un DBA. En fin de compte, toutes vos bases de données appartiennent à votre "datawarehouse d'entreprise", non?

Enfin, je ne reformulerai pas le dernier paragraphe de Scott Whitlock, en particulier

Je ne séparerais pas les tables en différentes bases de données physiques simplement pour des raisons de séparation.

est vraiment super important. Ne le faites pas s'il n'y a aucune raison.

Jalayn
la source
8

J'ai vu les pires cauchemars possibles dans l'architecture logicielle en raison de l'intégration des données, et la meilleure arme contre ce type de gâchis que j'ai rencontré jusqu'à présent id DDD-Style Bounded Contexts. Ce qui n'est pas très loin de "SOA done right", dans un certain sens.

Cependant, les données elles-mêmes ne sont pas le meilleur moyen d'attaquer le problème. Il faut se concentrer sur le comportement attendu / nécessaire et amener les données là où elles sont importantes. Nous pourrions finir par avoir une certaine duplication de cette façon, mais ce n'est normalement pas un problème par rapport aux blocs à l'évolution du système presque toujours associés aux architectures intégrées aux données.

Pour faire simple: si vous recherchez des systèmes faiblement couplés, ne restez pas couplés sur les données. Optez pour des systèmes encapsulés weel et un canal de communication bien structuré entre les deux, agissant comme "lingua franca".

ZioBrando
la source
1
Et ... répondre directement à la question du titre: "Oui, je considérerais comme une pratique risquée de partager une base de données dans une architecture SOA", si cela semble être la chose la plus raisonnable à faire, il y a probablement un grave défaut de conception.
ZioBrando
7

Le découplage des bases de données et la cohérence des données entre elles est une tâche de niveau expert. Il est très facile de se tromper et de se retrouver avec des problèmes de doublons, etc., que le système actuel est conçu pour éviter. Franchement, prendre un système qui fonctionne et faire cela est à peu près une garantie d'introduire de nouveaux bogues sans réelle valeur pour les utilisateurs.

HLGEM
la source
1

Si cela est fait correctement, la séparation des préoccupations commerciales en différentes bases de données (ou au moins différents schémas) est une vertu .

Veuillez consulter la description de Martin Fowler du modèle CQRS :

Au fur et à mesure que nos besoins deviennent plus sophistiqués, nous nous éloignons progressivement de [traiter un système d'information comme un magasin de données CRUD] ... Le changement que le CQRS introduit consiste à diviser ce modèle conceptuel en modèles distincts pour la mise à jour et l'affichage ... ici. Les modèles en mémoire peuvent partager la même base de données, auquel cas la base de données sert de communication entre les deux modèles. Cependant, ils peuvent également utiliser des bases de données distinctes , ce qui rend la base de données côté requête par une ReportingDatabase en temps réel. Dans ce cas, il doit y avoir un mécanisme de communication entre les deux modèles ou leurs bases de données.

Et les principes architecturaux de NServiceBus :

Séparation des requêtes de commande

Une solution qui évite ce problème sépare les commandes et les requêtes au niveau du système, même au-dessus de celles du client et du serveur. Dans cette solution, il existe deux "services" qui couvrent à la fois le client et le serveur - l'un en charge des commandes (créer, mettre à jour, supprimer), l'autre en charge des requêtes (lire). Ces services ne communiquent que par messages - l' un ne peut pas accéder à la base de données de l'autre ...

Et la séparation des responsabilités de commandement et de requête (CQRS)

Séparation des responsabilités de commande et de requête

La plupart des applications lisent les données plus fréquemment qu'elles n'en écrivent. Sur la base de cette déclaration, ce serait une bonne idée de faire une solution où facilement vous pouvez ajouter plus de bases de données à lire, non? Et si nous mettons en place une base de données dédiée uniquement à la lecture? Encore mieux; que se passe-t-il si nous concevons la base de données de manière à ce qu'elle soit plus rapide à lire? Si vous concevez vos applications en fonction des modèles décrits dans l'architecture CQRS, vous aurez une solution évolutive et rapide pour la lecture des données.

Jim G.
la source