Les microservices doivent-ils se parler?

30

Je conçois une application à l'aide de Micro-Services et je ne suis pas sûr du meilleur mécanisme à utiliser pour collecter des données à partir de plusieurs services.

Je pense qu'il y a deux options:

  • Intégrez un mécanisme de communication «inter-services» qui permet aux services de parler directement. La passerelle API appelle un service individuel, qui appelle ensuite d'autres services pour collecter des données, avant de renvoyer la réponse consolidée à la passerelle API. L'API renvoie ensuite la réponse à l'appelant. (Il devrait s'agir d'appels synchrones lorsque l'appel à serviceB nécessite la réponse de serviceA. IE Personne séparée et services d'adresse.)
  • Demandez à la passerelle API d'appeler directement chaque service et de consolider les données dans l'API avant de renvoyer la réponse.

Je penche vers la deuxième option, car le fait que les services se parlent introduirait un couplage, auquel cas je pourrais tout aussi bien concevoir une application monolithique. Cependant, il y a quelques inconvénients sérieux que je peux penser au large de ma tête avec cette option:

  • Le fait que l'API exécute plusieurs appels vers plusieurs services augmente la charge sur le serveur d'API, en particulier lorsque certains de ces appels bloquent.

  • Cette méthode signifierait que l'API doit être «consciente» de ce que l'application essaie de faire (IE Logic devrait être programmé dans l'API pour gérer l'appel des services à son tour, puis consolider les données), plutôt que simplement agir comme un «point final» stupide pour les micro-services.

Je voudrais savoir quelle est l'approche standard de ce problème et s'il y a une autre troisième option qui me manque?

KidCode
la source
Pouvez-vous fournir un certain contexte? Quelle est votre application et qu'est-ce qu'elle essaie de faire
Ewan
Ma conjecture se situerait quelque part entre vos deux options: chaque micro-service communique avec d'autres micro-services selon les besoins pour faire son travail. Et la passerelle API pourrait également être considérée comme un micro-service, qui délègue principalement le travail à d'autres services.
Bart van Ingen Schenau
Je dirais que la composition de microservices côté serveur va à l'encontre de l'objectif principal d'avoir des microservices pour commencer. L'idée est de rendre les services indépendants et de laisser l'orchestration au client. Mais peut-être que je ne suis pas pratique
Sridhar Sarnobat

Réponses:

21

Je déconseille généralement que les microservices établissent une communication synchrone les uns avec les autres, le gros problème est le couplage, cela signifie que les services sont désormais couplés les uns aux autres, si l'un d'entre eux échoue, le second est maintenant totalement ou partiellement dysfonctionnel.

Je ferais une distinction claire entre les opérations de changement d'état et les opérations de lecture ( séparation des requêtes de commande CQS ). Pour les opérations de changement d'état, j'utiliserais une sorte d'infrastructure de messagerie et j'irais au feu et j'oublierais. Pour les requêtes, vous utiliseriez une communication de réponse de demande synchrone et pourriez utiliser une API http ou simplement aller directement à votre magasin de données.

Si vous utilisez la messagerie, vous pouvez également consulter la publication d'abonnement pour déclencher des événements entre les services.

Un autre point à considérer est le partage de données (transactionnel) (par opposition aux vues en lecture seule) si vous exposez votre état interne, le lecteur pourrait obtenir le mauvais état de vos données, ou la mauvaise version, et pourrait également verrouiller vos données?

Enfin et surtout, essayez de faire tout votre possible pour garder vos services autonomes (au moins au niveau logique).

J'espère que cela a du sens.

Sean Farmar
la source
11

Cela dépend de la raison pour laquelle vous avez besoin de ces données. Si c'est pour l'interface utilisateur, c'est parfaitement bien. De plus, c'est comme ça que ça devrait être. Chris Richardson a une belle explication de ce concept , et Sam Newman a un excellent article sur un concept très similaire appelé Backends for Frontends .

Mais si vous en avez besoin pour une certaine logique, il est probable que vos limites de service soient erronées.

Il y a plusieurs caractéristiques que le bon sens nous dit que nos services devraient posséder . Elles sont:

  1. Couplage bas. Si vous apportez des modifications au service A, vous ne voulez pas qu'elles affectent le service B.
  2. Haute cohésion. Si vous devez implémenter une fonctionnalité, vous souhaitez que le moins de services possible soit affecté.
  3. Grande autonomie. Si un service échoue, vous ne voulez pas que tout le système soit arrêté.
  4. Granularité correcte. Vous ne voulez pas que vos services soient trop bavards, car votre réseau est plus complexe que vous ne le pensez.
  5. Les services doivent communiquer via des événements. Vous ne voulez pas que votre service soit au courant les uns des autres car il réduit la maintenabilité. Réfléchissez à ce qui se passe si vous devez ajouter un nouveau service.
  6. Données décentralisées. Un service ne doit pas partager la façon dont les informations sont stockées. Tout comme un bon objet, il expose le comportement, pas les données.
  7. Chorégraphie de service sur orchestration.

Pour ce faire, traitez vos frontières de services comme des capacités commerciales . Un processus formel d'identification des limites de service ressemble à ceci:

  1. Identifiez les limites de niveau supérieur. J'aime les considérer comme des étapes que votre organisation doit suivre pour atteindre son objectif commercial, obtenir sa valeur commerciale. Vous pouvez avoir l'idée d'étapes de base en jetant un œil à la chaîne de valeur de Porter .
  2. Au sein de chaque service, approfondissez. Identifier les unités autonomes des enfants avec leurs propres responsabilités.
  3. Attention à la façon dont ils communiquent. Les services corrects communiquent principalement via des événements. Pensez à votre structure organisationnelle. La communication à l'intérieur d'eux est assez intensive, bien que généralement quelques événements externes soient exposés.

Un exemple d'application de cette approche pourrait présenter un certain intérêt.

Zapadlo
la source
1

Je pencherais également pour la deuxième approche par défaut, mais peut-être pas dans votre "passerelle API", mais je considérerais qu'il est tout à fait raisonnable de créer un nouveau micro-service dont le seul but était d'orchestrer les demandes à d'autres micro-services et de représenter les données sous une forme de niveau supérieur. Dans une architecture de micro-services, je serais opposé à ce que les micro-services "de base" communiquent directement entre eux.

Pour rendre cela un peu moins subjectif, disons qu'un service dépend d' un autre si le premier nécessite des données ou des services du second, directement ou indirectement . En termes mathématiques, nous voulons que cette relation soit un ordre partiel et non un précommande . Sous forme de diagramme, si vous avez tracé votre diagramme de dépendance, vous devriez obtenir un diagramme de Hasseet ne pas avoir de cycles (dirigés). (Dans un diagramme de Hasse, les bords sont implicitement dirigés du bas vers le haut.) À titre indicatif, vous souhaitez que les trajets de haut en bas soient généralement plus courts. Cela signifie que vous voulez dépendre plus directement des choses par défaut. Les raisons en sont que cela minimise le nombre de choses qui peuvent mal tourner pour une demande particulière, cela minimise les frais généraux et cela réduit la complexité. Ainsi, dans le cas «idéal» de cette métrique, le diagramme de Hasse n'aurait que deux niveaux. Bien sûr, il existe de nombreuses raisons pour lesquelles vous souhaiterez peut-être introduire des services intermédiaires tels que la mise en cache, la consolidation, l'équilibrage de charge, la gestion des pannes.

Pour approfondir votre deuxième préoccupation d'avoir une API Gateway «intelligente», un modèle qui gagne du terrain maintenant avec des frameworks comme Falcor et Relay / GraphQL consiste à demander plus de spécifications sur ce qu'il faut faire pour que la «API Gateway» puisse génériquement exécuter ces spécifications sans avoir à savoir ce que cela GetTimelineimplique. Au lieu de cela, il obtiendrait une demande telle que "demander ces informations utilisateur au service utilisateur et obtenir ces messages à partir du service postal" ou autre.

Derek Elkins
la source
0

Je soupçonne que votre besoin de services de «s'appeler» les uns les autres indique que vous opérez avec un système qui n'a pas été bien architecturé, car ce besoin de microservices de «s'appeler» les uns les autres est une forme de couplage qui apparaît rarement lorsque les microservices sont conçus de manière appropriée.

Pouvez-vous expliquer davantage le problème que vous essayez de résoudre? En anglais simple?

Ben
la source