web-dev-qa-db-fra.com

Partage de code et de schéma entre microservices

Si vous optez pour une architecture de microservices dans votre organisation, ils peuvent partager la configuration via zookeeper ou son équivalent. Cependant, comment les différents services devraient-ils partager un schéma de base de données commun? constantes communes? et les utilitaires communs?

Une façon serait de placer tous les microservices dans le même référentiel de code, mais cela contredirait le découplage fourni avec les microservices ...

Une autre façon serait de faire en sorte que chaque microservice soit complètement indépendant, mais cela entraînerait une duplication de code et une duplication des données dans les bases de données distinctes que chaque microservice devrait contenir.

Encore une autre façon serait d'implémenter des microservices fonctionnels sans contexte\état, mais ce n'est généralement pas réaliste et pousserait l'architecture à avoir un concentrateur central qui maintient le contexte\état et beaucoup de trafic de\vers lui.

Quelle serait une manière pratique, évolutive, efficace et, espérons-le, belle de partager du code et un schéma entre des microservices?

47
Jonathan

En ce qui concerne le code commun, la meilleure pratique est d'utiliser un système d'emballage. Donc, si vous utilisez Java, utilisez maven, si vous utilisez Ruby alors Gems, if python puis pypi etc. Idéalement, un système d'emballage ajoute peu de friction pour que vous peut avoir un référentiel (par exemple, git) pour une bibliothèque commune (ou plusieurs bibliothèques communes pour différents sujets) et publier leurs artefacts via un référentiel d'artefacts (par exemple, maven/gems/pypi privé). Ensuite, dans le microservice, vous ajoutez une dépendance sur le libérations requises. La réutilisation du code est donc facile. Dans certains cas, les systèmes de conditionnement ajoutent un peu de friction (maven pour un) donc on peut préférer utiliser un seul dépôt git pour tout et une configuration de projet multi-module. Ce n'est pas aussi propre que le première approche mais fonctionne aussi bien et pas trop mal. Les autres options sont d'utiliser le sous-module git (moins souhaité) ou le sous-arbre git (meilleur) afin d'inclure le code source dans un seul référentiel "parent".

Concernant le schéma - si vous voulez jouer par le livre, alors chaque microservice a sa propre base de données. Ils ne se touchent pas les données les uns des autres. Il s'agit d'une approche très modulaire qui semble à première vue ajouter un peu de frottement à votre processus, mais finalement je pense que vous me remercierez. Il permettra une itération rapide sur vos microservices, par exemple, vous souhaiterez peut-être remplacer une implémentation de base de données par une autre implémentation de base de données pour un service spécifique. Imaginez faire cela lorsque tous vos services utilisent la même base de données! Bonne chance avec ça ... Mais si chaque service utilise sa propre base de données, le service résume correctement la base de données (par exemple, il n'accepte pas les requêtes SQL comme appels d'API par exemple ;-)) puis en changeant mysql en Cassandra devient soudainement réalisable. Il y a d'autres avantages à avoir des bases de données complètement isolées, par exemple la charge et la mise à l'échelle, la recherche de goulots d'étranglement, la gestion, etc.

Donc en bref - code commun (utilitaires, constantes, etc.) - utilisez un système de conditionnement ou une liaison de code source comme git-tree

Base de données - vous ne touchez pas la mienne, je ne touche pas la vôtre. C'est le meilleur moyen de contourner cela.

HTH, Ran.

31
Ran

L'approche "la plus pure", c'est-à-dire celle qui vous donne le moins de couplage, est de ne partager aucun code.

Si vous trouvez que deux services (appelez-les A et B) ont besoin de la même fonctionnalité, vos options sont les suivantes:

  • se séparer s'il est désactivé en tant que service distinct C, donc A et B peuvent utiliser C
  • mordre la balle et dupliquer le code

Bien que cela puisse sembler gênant, vous évitez le problème (pas rare) de créer une bibliothèque "utilitaire" ou "commune" ou "infrastructure" dont tout le monde dépend, et qui est alors vraiment difficile à mettre à niveau et à modifier (c'est-à-dire qui couple indirectement le prestations de service).

En pratique, comme d'habitude, c'est un compromis.

  • Si la fonctionnalité partagée est substantielle, j'irais pour un service séparé.
  • S'il ne s'agit que de constantes, une bibliothèque partagée pourrait être la meilleure solution. Vous devez cependant faire très attention à la compatibilité descendante.
  • Pour les données de configuration, vous pouvez également implémenter un service spécifique, en utilisant éventuellement une technologie existante telle que LDAP.
  • Enfin, pour un code simple susceptible d'évoluer indépendamment, la duplication peut être la meilleure solution.

Cependant, le meilleur dépendra de votre situation et de votre problème spécifiques.

14
sleske

D'après mon expérience de projet

Partager un WSDL lors de l'utilisation de SOAP (pas le code du modèle de service, car ils doivent être générés à partir du WSDL). Lors de l'utilisation de REST, avoir des modèles distincts (copier oui mais pas partager) pour le client et le serveur . Dès que le deuxième ou le troisième consommateur entre en jeu, vous aurez des ennuis. Gardez-les découplés. Le fonctionnement et l'utilisation d'un service ont changé dans mon passé plus souvent que les structures de données. Un autre client veut utiliser votre service ou une deuxième version doit être utilisée en même temps.

Quelques réflexions supplémentaires

Le partage est partiellement contradictoire avec l'évolutivité. Partager-rien et partager-certains/partager-tous ont des avantages et des inconvénients. Ne rien partager vous donne une flexibilité totale à tout moment. Les microservices sont des composants indépendants fournissant des services de domaine particuliers.

Le partage de modèles de données de domaine métier est un modèle courant ( http://www.ivarjacobson.com/resources/resources/books/#object%20oriented%20software ) qui empêche les doublons de celui-ci. Étant donné que les microservices divisent et conquièrent les parties métier, il peut être difficile de partager quelque chose du modèle de données du domaine métier.

Les microservices communiquent entre eux, je comprends donc la nécessité de partager ces modèles de données de communication (principalement basés sur HTTP). Le partage de ces modèles de données peut être correct si vous avez une correspondance un à un entre le fournisseur de services et le consommateur. Dès que vous avez plusieurs consommateurs pour un service nécessitant différents modèles/domaines dans le modèle, cela devient difficile.

4
mp911de

En ce qui concerne le principe du FAI (principe de séparation des interfaces), les clients devraient dépendre de l'interface et non des implémentations.

0
Burak savurur