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:
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?
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 (CQS Command Query Separation ). 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.
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 à ce sujet 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 nos services devraient posséder . Elles sont:
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:
Un exemple d'application de cette approche pourrait être intéressant.
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 micro-service nouveau dont le seul but était de orchestrez les demandes vers d'autres micro-services et représentez 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 de 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 Hasse et 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 problèmes pouvant survenir pour une demande particulière, minimise les frais généraux et 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 l'API Gateway "intelligente", un modèle qui gagne du terrain maintenant avec des cadres comme Falcor et Relay / GraphQL est de faire des requêtes plus de spécifications sur ce qu'il faut faire pour que la "passerelle API" puisse exécuter ces spécifications de manière générique sans avoir à savoir ce que GetTimeline
implique. 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 chose.
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?