web-dev-qa-db-fra.com

Microservices et procédures stockées

Les procédures stockées sont-elles considérées comme une mauvaise pratique dans une architecture de microservices?

Voici mes pensées:

  • la plupart des livres sur les microservices recommandent une base de données par microservice. Les procédures stockées fonctionnent généralement sur une base de données monolithique.

  • encore une fois, la plupart des livres d'architecture de microservices déclarent qu'ils doivent être autonomes et faiblement couplés. L'utilisation de procédures stockées écrites, disons spécifiquement dans Oracle, couple étroitement le microservice à cette technologie.

  • la plupart des livres d'architecture de microservices (que j'ai lus) recommandent que les microservices soient orientés métier (conçus en utilisant conception pilotée par le domaine (DDD)). En déplaçant la logique métier dans des procédures stockées dans la base de données, ce n'est plus le cas.

Des réflexions à ce sujet?

34
Johnny Alpha

Rien n'interdit ni ne plaide explicitement contre l'utilisation de procédures stockées avec des microservices.

Avertissement: je n'aime pas les procédures stockées du PDV d'un développeur, mais cela n'est en aucun cas lié aux microservices.

Les procédures stockées fonctionnent généralement sur une base de données monolithique.

Je pense que vous succombez à une erreur logique.

Les procédures stockées sont en déclin de nos jours. La plupart des procédures stockées qui sont encore utilisées proviennent d'une base de code plus ancienne qui a été conservée. À l'époque, les bases de données monolithiques étaient également beaucoup plus répandues que lorsque les microservices étaient devenus populaires.

Les processus stockés et les bases de données monolithiques se produisent tous deux dans d'anciennes bases de code, c'est pourquoi vous les voyez plus souvent ensemble. Mais ce n'est pas un lien de causalité. Vous n'utilisez pas de proc stockés car vous avez une base de données monololithique. Vous n'avez pas de base de données monolithique car vous utilisez des procs stockés.

la plupart des livres sur les microservices recommandent une base de données par microservice.

Il n'y a aucune raison technique pour laquelle ces petites bases de données ne peuvent pas avoir de procédures stockées.

Comme je l'ai mentionné, je n'aime pas les proc stockés. Je les trouve encombrants et résistants aux futurs entretiens. Je pense que la diffusion de sprocs sur de nombreuses petites bases de données aggrave encore les problèmes que je n'aime pas déjà. Mais cela ne signifie pas que cela ne peut pas être fait.

encore une fois, la plupart des livres d'architecture de microservices indiquent qu'ils doivent être autonomes et faiblement couplés. L'utilisation de procédures stockées écrites spécifiquement dans Oracle associe étroitement le microservice à cette technologie.

De l'autre côté, le même argument peut être avancé pour tout ORM utilisé par votre microservice. Tous les ORM ne prendront pas non plus en charge toutes les bases de données. Le couplage (en particulier son étanchéité) est un concept relatif. Il s'agit d'être aussi lâche que possible.

Les sprocs souffrent d'un couplage étroit en général, indépendamment des microservices. Je déconseille les sprocs en général, mais pas particulièrement parce que vous utilisez des microservices. C'est le même argument que précédemment: je ne pense pas que les sprocs soient la voie à suivre (en général), mais cela pourrait simplement être mon parti pris, et ce n'est pas lié aux microservices.

la plupart des livres msa (que j'ai lus) recommandent que les microservices soient orientés métier (conçus en utilisant ddd). En déplaçant la logique métier dans des procédures stockées dans la base de données, ce n'est plus le cas.

Cela a toujours été mon principal reproche concernant les sprocs: la logique métier dans la base de données. Même quand ce n'est pas l'intention, cela a toujours tendance à finir de cette façon.

Mais encore une fois, ce reproche existe, que vous utilisiez ou non des microservices. La seule raison pour laquelle cela ressemble à un problème plus important est que les microservices vous poussent à moderniser l'ensemble de votre architecture, et les sprocs ne sont plus aussi appréciés dans les architectures modernes.

46
Flater

Pour écrire un logiciel, vous devez vous associer étroitement à une technologie.

À tout le moins à l'environnement d'exécution fourni par le langage de programmation en cours de développement.

Plus généralement, vous constaterez que votre micro-service est étroitement lié à plusieurs technologies:

  • Network Service Framework pour fournir des implémentations de protocole HTTP/SSL/SOAP de haut niveau
  • Référentiel/ORM/DAO Framework pour fournir la persistance.
  • Cadres de manipulation des données pour fournir des outils pour travailler avec les données.
  • Processus/Threading/OS Framework pour fournir un accès aux ressources du système d'exploitation telles que le multitâche, le système de fichiers, la mémoire, le calcul GPU, les cartes d'extension, etc.

Et c'est de faire un micro-service à nu.

Procédures stockées

Une procédure stockée est simplement une autre technologie que vous pouvez choisir d'utiliser ou de ne pas utiliser. Cela ne rend pas magiquement votre code monolithique ou micro.

Mais c'est:

  • Une autre technologie. Chaque technologie présente dans l'application diminue la probabilité que n'importe quel programmeur donné puisse lire, comprendre et faire des choix de conception judicieux pour ce mélange de technologies.
  • Un langage utilisant un paradigme de programmation différent. Il est beaucoup trop facile pour les non-experts d'essayer d'imposer leur propre perspective impérative, fonctionnelle, OO, etc ..., ce qui conduit souvent à des résultats moins que stellaires.
  • Une API. Qui doit être maintenu comme toute autre classe dans la base de code. Cela signifie également que la base de données fournit une interface non générique. Cela rend plus difficile à la fois le remplacement du moteur de base de données lui-même et l'application transparente d'un comportement générique comme dans la mise en cache de la mémoire.
  • Un artefact. Qui doit être versionné, testé et déployé. Cela peut être fait, mais les bases de données sont des artefacts vivants nécessitant une approche différente. Vous ne pouvez généralement pas simplement supprimer l'original et le remplacer. Souvent, une orchestration minutieuse des modifications au fil du temps est nécessaire pour migrer le système vers l'état souhaité.

Chacun de ces éléments représente un coût réel. Dans certains cas, le coût est justifiable, dans d'autres non.

Vous paieriez presque le même ensemble de coûts en hébergeant un moteur de script. La seule réduction est que vous pouvez choisir le même paradigme de programmation que le langage hôte.

Business Logic

Le déplacement de règles métier dans la base de données est une mauvaise pratique. Tout simplement pas à cause des procédures stockées.

C'est une mauvaise pratique, car la base de données et la logique métier fonctionnent à différents niveaux de cisaillement.

  • Une base de données dans une application mature peut être utilisée pendant des décennies. Généralement, ces systèmes auront le moteur régulièrement mis à jour, mais la base de données elle-même a été migrée. Il n'a pas été tué et reconstruit depuis le début. Il n'y a aucune raison pour qu'un micro-service ne puisse pas durer aussi longtemps.

  • Comparez des décennies à la rapidité avec laquelle les règles métier changent. D'après mon expérience, une vieille règle commerciale a peut-être quelques années, mais la plupart changent cependant rapidement, et vous ne pouvez jamais dire laquelle changera ensuite. Une nouvelle exigence d'un régulateur, un ancien produit étant mis hors service, des changements à l'en-tête de lettre, des changements au nombre d'employés qui rendent compte à un patron, etc, etc, etc ...

Si la logique métier est répartie entre les couches de cisaillement, en particulier dans une couche plus lente et à durée de vie plus longue, elle générera une résistance au changement. Ce n'est pas forcément une mauvaise chose. Après tout, la seule base de données qui n'a aucune logique métier est un triple magasin.

Le simple fait de spécifier un schéma de table déplace la logique métier dans la base de données.

Architecture

Vous vous contentez d'utiliser l'outil approprié pour le problème approprié, sans avoir besoin de trop d'outils, ni le rendre trop difficile à résoudre, afin de trouver et de maintenir une solution.

Ce n'est pas facile.

Mais pensons à l'impensable, comment maintiendriez-vous la logique métier répartie sur plusieurs langues?

  • Un catalogue ... pour que chaque implémentation de règles métier puisse être suivie et maintenue.
  • Des tests ... qui pourraient être utilisés par rapport à chaque règle métier, quel que soit l'endroit et la manière dont elle a été mise en œuvre.
  • Une implémentation de référence .. pour qu'en cas de divergence, une source de vérité existe (ou du moins une source de débat).

Mais cela a aussi un coût.

  • Est-il préférable de permettre aux règles métier d'avoir de nombreuses implémentations? Cela peut chacun profiter des compétences de l'équipe et des dispositions du cadre, mais avoir besoin de contrôles de qualité stricts pour éviter d'avoir de nombreux petits caprices?
  • Ou vaut-il mieux avoir une seule source de vérité, écrite dans une seule langue? Sans doute moins cher à mettre en œuvre, mais aussi une source unique de défaillance, lui-même un composant monolithique qui résiste au changement face à différentes plates-formes, cadres ou outils à inventer?
24
Kain0_0

Je préfère ma réponse en disant que je maintiens en fait quelques microservices qui utilisent des procédures stockées. J'ai également écrit de nombreuses procédures stockées à différents moments de ma carrière, et je suis définitivement d'accord pour dire que les choses peuvent très, très mal tourner si elles sont utilisées de manière incorrecte.

Donc, la réponse courte est non, les procédures stockées ne sont pas intrinsèquement mauvaises dans une architecture de microservice. Mais vous devez comprendre:

  1. Vous ajoutez des obstacles à la substitution des moteurs de stockage. Si certaines caractéristiques opérationnelles ou de performances ou limitations de fonctionnalités vous obligent à changer de moteur de stockage, le coût sera plus élevé car vous allez écrire et tester beaucoup de nouveau code. L'exécution de plusieurs moteurs de stockage (pendant une phase de migration ou pour isoler des activités en fonction des besoins de performances) peut entraîner des problèmes de cohérence, sauf si vous utilisez la validation en deux phases (2PC), qui présente elle-même des problèmes de performances.
  2. Vous avez une autre API à gérer, ce qui signifie que vos dépendances peuvent se briser. L'ajout, la suppression ou la modification des types de paramètres sur les procédures peut casser le code existant. La même chose se produit avec les tables et les requêtes, mais vos outils peuvent être moins utiles pour localiser les problèmes potentiels. Les problèmes avec les procédures stockées sont généralement détectés lors de l'exécution, très tard dans le processus de développement/déploiement.
  3. Vos autorisations de base de données sont devenues plus compliquées. Une procédure s'exécute-t-elle en tant qu'utilisateur connecté ou en tant que autre rôle? Vous devez y penser et gérer cela (espérons-le de manière automatisée).
  4. Vous devez pouvoir migrer vers de nouvelles versions en toute sécurité. Souvent, une procédure doit être supprimée et recréée. Encore une fois, les autorisations peuvent vous causer des problèmes.
  5. La restauration d'une migration qui a échoué peut impliquer un effort supplémentaire. Lorsque l'environnement de production est séparé des développeurs, les choses deviennent encore plus difficiles.

Voici quelques utilisations des procédures stockées qui, je pense, valent souvent la peine:

  1. Application de l'historique des modifications (journaux d'audit). Les déclencheurs sont couramment utilisés à cette fin et les déclencheurs sont des procédures stockées. Il est également possible dans certaines bases de données d'interdire entièrement les insertions et les mises à jour pour le rôle d'application: les clients exécutent des procédures qui sont exécutées en tant que rôle différent avec les autorisations appropriées et qui appliquent tous les comportements nécessaires.
  2. Extension des contraintes de contrôle. Cela peut vous amener sur le territoire de la logique métier, mais il existe des cas où les outils de contrainte intégrés d'une base de données peuvent ne pas être suffisants pour ce dont vous avez besoin. Souvent, le meilleur moyen d'exprimer des chèques est d'utiliser un code impératif, et vous risquez de laisser entrer de mauvaises données si vous dépendez de votre application pour le faire pour vous.
  3. Encapsulation de requêtes complexes lorsqu'une vue est inappropriée ou trop compliquée. J'ai vu quelques cas où une vue correcte nécessite du SQL extrêmement complexe qui peut être exprimé de manière beaucoup plus compréhensible dans une procédure stockée. C'est probablement rare, mais cela se produit.

En général, je vous suggère d'essayer d'abord les vues et de recourir aux procédures uniquement lorsque cela est nécessaire. Des vues bien conçues peuvent réellement fonctionner comme une API, résumant les détails de la façon dont les tables sous-jacentes sont interrogées. Augmenter votre API (vues) avec des procédures stockées est logique dans certaines circonstances. Il est même possible d'émettre du JSON directement à partir d'une requête SQL, en contournant tout le désordre de mappage des données des résultats de la requête au modèle de données de votre application. Que ce soit une bonne idée est quelque chose que vous devez déterminer en fonction de vos propres besoins.

Étant donné que vous devez déjà gérer vos ressources de base de données (schéma, autorisations, etc.) via un outil automatisé, non, les procédures stockées ne sont pas intrinsèquement mauvaises pour les microservices.

8
ngreen

Les procédures stockées sont des détails d'implémentation. Les fonctions de base de données, les lambdas ou un script Shell stockés quelque part dans le système de fichiers sont tous des détails d'implémentation et non pertinents pour l'architecture.

la plupart des livres sur les microservices recommandent une base de données par microservice.

Ok, nous pouvons donc coder les procédures stockées dans ces bases de données.

encore une fois, la plupart des livres d'architecture de microservices déclarent qu'ils devraient être autonomes et couplés de manière lâche

Entre les capacités métier, les cycles de vie du développement, la gestion, les déploiements, les emplacements des équipes, etc. Rien à voir avec les détails d'implémentation Les microservices ne résolvent pas un problème technique (bien au contraire). Ils viennent résoudre des problèmes de gestion et de time-to-market. C'est une stratégie, pas une tactique. Une façon d'échouer à moindre coût. Si une certaine capacité commerciale s'avère sans valeur, nous la laissons tomber sans gâcher d'autres capacités, déploiements, gestion de projets, versions ...

Notez que le "split" agit déjà comme un agent de découplage. Supposons que nous ayons deux services, A est soutenu par Oracle et B par MongoDB. Si nous ne brisons pas la règle d'or du découplage, il devrait être possible de supprimer A + Oracle avec des effets secondaires négligeables sur B.

L'utilisation de procédures stockées écrites spécifiquement dans Oracle associe étroitement le microservice à cette technologie.

Cela pourrait entraîner un blocage du fournisseur. Plusieurs fois, le vendeur est imposé par l'entreprise pour des raisons historiques ou contractuelles1. Il est important de savoir comment ne pas verrouiller notre code sur le fournisseur. Par exemple, certains ORM et frameworks implémentent un nouveau langage de requête qui masque les fonctions et fonctionnalités intégrées de la base de données.

Bien que, si nos services sont suffisamment micro, le blocage des fournisseurs ne soit plus un problème car il affecte une petite partie de l'ensemble. Une petite pièce qui devrait pouvoir être remplacée (ou isolée) rapidement.

la plupart des livres MSA (que j'ai lus) recommandent que les microservices soient orientés métier (conçus en utilisant DDD).

Cela devrait être axé sur les affaires et voici la chose. Toutes les entreprises ne profitent pas de DDD. DDD et microservices se chevauchent en de nombreux points, mais ils ne sont pas de cause à effet. On pourrait se retrouver avec un écosystème de microservices composé de services anémiques. Ou composé d'un mélange des deux: services mettant en œuvre un domaine complexe et services anémiques muets fournissant des POJO directement à partir de la base de données. Il n'y a rien de mal à cela.

Concernant les livres, ils se concentrent uniquement sur l'exécution de la stratégie. Les tactiques - comment tirer parti de l'informatique distribuée - comment le faire fonctionner avec succès, mais elles sont (généralement) agnostiques à la stratégie. Les stratégies varient d'une entreprise à l'autre et dépendent rarement des développeurs. Donc, nous devons encore extrapoler et adapter ce que les livres disent à nos besoins, exigences et contraintes spécifiques. L'objectif est de rendre la stratégie commerciale rentable et durable.

Gardez toujours à l'esprit que toute architecture est un moyen pour une fin. Les règles commerciales. Nous ne construisons pas d'écosystèmes de microservices pour la mode ou pour l'amour de l'art.

4
Laiv

Cela n'a rien à voir avec les microservices.

Les procédures stockées peuvent avoir un sens si votre service a une architecture en couches `` à l'ancienne '' dans laquelle la base de données est le fondement du service, avec des couches d'accès aux données et de logique métier au-dessus. L'interface entre le service et la base de données dans une telle architecture est très spécifique aux détails les plus intimes du service. En règle générale, il existe des adaptateurs spécifiques au service pour chaque type de base de données prise en charge, et la spécificité de l'API exposée par l'adaptateur permet d'utiliser des procédures stockées dans les couches sous-jacentes.

Il y a beaucoup de problèmes avec de telles architectures. Plus important encore, cela rend la plupart de la logique très difficile à tester unitaire. Ces architectures ne sont plus en faveur.

Si vous utilisez une "architecture propre", une "architecture d'oignon" de style plus récent, ou similaire, la base de données sera une dépendance injectée, spécifiée au niveau des couches externes. Puisqu'elle est définie dans les couches externes, l'interface fournie pour la base de données doit être générique. Il ne peut pas refléter les détails les plus intimes du service, car ces détails doivent être cachés des couches les plus externes de l'architecture. Définir une interface de procédure stockée générique qui peut fonctionner avec n'importe quelle base de données ou faisceau de tests unitaires est incroyablement difficile, et pas vraiment nécessaire, de sorte que les procédures stockées ne sont pas souvent pratiques dans ce type d'architectures.

La relation avec les microservices est simplement que les microservices sont nouveaux et ascendants - nous ne faisons plus de monolithes - et que ces nouveaux styles architecturaux sont également ascendants - nous ne faisons plus de couches plates.

1
Matt Timmermans