Les services doivent-ils communiquer directement entre eux dans une architecture de microservices?

10

J'ai un certain nombre de services Web qui forment une application Web. Les clients peuvent accéder à ces services via des appels d'API REST.

Ces services devraient-ils pouvoir communiquer directement entre eux? Si c'est le cas, cela ne les rendrait-il pas contraires au concept des microservices?

Le client doit-il les appeler directement les uns après les autres pour obtenir les données dont il a besoin pour charger une page Web sur le client?

Ou devrais-je avoir une autre couche au-dessus de mes services, qui gère une demande du client, récupère les données de cette demande, puis les renvoie au client?

cod3min3
la source
Si les choses sont complètement découplées, ce sont des produits complètement séparés. Ainsi, l'utilisateur devrait se connecter à la connexion Contoso, puis la connexion Contoso dirait "Vous êtes maintenant connecté!" ... et ensuite ils vont à Contoso Sensitive Data Storage, cochez la case qui dit "Oui, je suis connecté "... puis copiez-collez les données de celles-ci dans le processeur de données Contoso ...
user253751

Réponses:

16

Si vous voulez que vos services ressemblent à cette image, alors oui: entrez la description de l'image ici ce n'est pas comme si vous ne pouviez pas le faire, mais la plupart du temps cela aura de mauvaises conséquences. La communication via REST ne découplera pas significativement vos services. Lorsque certaines interfaces de service changent, tous les services dépendants doivent très probablement être modifiés et redéployés. De plus, lors du redéploiement du service, vous devrez désactiver tous les services dépendants, ce qui n'est pas considéré comme une bonne conception pour les normes de haute disponibilité.

En fin de compte, vous aurez une application de microservices qui est plus lente que l'application monolithique alternative, mais ayant presque tous les mêmes problèmes!

Je dois être en désaccord avec @Robert Harvey

En pratique, cependant, un ou plusieurs de vos microservices (peut-être tous) parleront à un magasin de données central comme une base de données SQL.

La base de données d'intégration est un contre -modèle bien connu

Une bien meilleure solution consiste à utiliser un modèle de publication-abonnement afin de rendre la communication entre vos services asynchrone:

entrez la description de l'image ici

S'il vous plaît jetez un œil à la manière CQRS / ES de mettre en œuvre cette méthode de communication, Greg Young et d'autres gars proposent des tonnes de belles vidéos sur le sujet. Juste google pour le mot clé "CQRS / ES". Dans cette approche, chaque service deviendra à la fois éditeur et abonné, permettant ainsi aux services d'être beaucoup moins couplés.

Voici une bonne série d'articles sur les microservices qui éclaire la controverse autour du sujet. Explication très détaillée avec de belles illustrations.

IlliakaillI
la source
2
Eh bien, tout d'abord, je n'ai entendu le terme «base de données d'intégration» nulle part sauf de Fowler. Ne prenez pas quelque chose comme évangile juste parce qu'un gars l'a dit. Deuxièmement, vous n'avez pas suffisamment d'informations pour appeler ce que j'ai décrit une "base de données d'intégration". Troisièmement, Fowler appelle en fait de telles bases de données utiles dans les bonnes circonstances, dans le même article que vous avez lié. J'aime l'idée d'un bus d'événements, bien que je ne vois pas en quoi c'est si différent que d'appeler l'API habituelle du microservice, sauf si vous pouvez augmenter l'efficacité.
Robert Harvey
Merci Robert, j'ai lié l'article de Fowler pour mieux illustrer l'idée, pas pour contester l'autorité. La façon dont vous avez décrit cette approche ressemble beaucoup à celle d'une base de données d'intégration. Si c'est différent - ce n'est pas évident du tout. En ce qui concerne les bonnes circonstances - je pense que l'intégration de microservices via une base de données n'est pas une bonne idée car elle nous ramène à une architecture monolithique.
IlliakaillI
1
Bien sûr: chaque microservice parlera à sa propre base de données distincte ou aux tables de la même base de données qui ne sont pas liées aux tables d'autres services. De cette façon, les services n'échangent jamais d'informations via la base de données, ce qui signifie que vous pouvez facilement évoluer horizontalement et qu'il y aura beaucoup moins de goulots d'étranglement. Et parce qu'ils ne partagent pas les mêmes tables - les changements dans une partie de l'application auront moins de chances d'influencer d'autres parties.
IlliakaillI
1
Vous ne pouvez pas affirmer catégoriquement cela comme un absolu. Il peut y avoir deux services qui ont besoin des mêmes informations dans la même base de données, ils n'en ont besoin qu'occasionnellement, il n'y a pas de problème de mise à l'échelle pour y accéder de cette façon, les deux services accèdent déjà à la base de données à d'autres fins de toute façon, donc debout un bus de service ou un point de terminaison API juste pour accomplir cela serait ridicule.
Robert Harvey
1
Mais pour obtenir une valeur commerciale, vous voulez combiner des données - "montrez-moi tous les systèmes d'égouts qui auront une capacité de stockage insuffisante compte tenu des données radar suivantes de la pluie entrante, et coloriez cette carte des municipalités en utilisant le résultat". Si vous divisez toutes vos données en services, cela signifie simplement que vous ne pouvez combiner les données que plus tard. Si vous interdisez aux services de se parler, vous vous forcez simplement à déplacer toutes les données vers un client et à y joindre les données. Vous VOULEZ coupler des données quelque part, car c'est ce qui au final donne une valeur d'application.
RemcoGerlich
8

Vous aurez beaucoup de très bonnes idées en lisant ce que Udi Dahan a à dire sur la SOA .

Un service est l'autorité technique pour une capacité commerciale spécifique. Toute donnée ou règle doit appartenir à un seul service.

Cela signifie que, même lorsque les services publient et s'abonnent aux événements les uns des autres, nous savons toujours quelle est la source de vérité faisant autorité pour chaque élément de données et règle.

En outre, lorsque nous examinons les services du point de vue des capacités commerciales, nous constatons que de nombreuses interfaces utilisateur présentent des informations appartenant à différentes capacités - le prix d'un produit et son stock ou non. Afin de nous conformer à la définition ci-dessus des services, cela nous amène à comprendre que de telles interfaces utilisateur sont en fait un mashup - chaque service ayant le fragment de l'interface utilisateur traitant de ses données particulières.

En ce qui concerne spécifiquement la composition de l'interface utilisateur, l'article de Mauro Servienti sur la composition de l'interface utilisateur est un bon point de départ. Voir aussi la vidéo d'Udi, disponible ici .

Ces services devraient-ils pouvoir communiquer directement entre eux? Si c'est le cas, cela ne les rendrait-il pas contraires au concept des microservices?

Si deux services échangent des messages, vous obtiendrez un couplage. La principale réponse est qu'ils se couplent à l'API de l'autre service - le contrat que le service promet de maintenir stable même lorsque ses internes changent.

Au-delà de cela, des techniques telles que la découverte de services peuvent réduire la dépendance vis-à-vis d'un fournisseur de services spécifique, et les courtiers de messages peuvent dissocier les producteurs et les consommateurs (ils ont toujours besoin de comprendre les messages des autres, et comment interagir avec l'API du courtier de messages - il n'y a pas de magie ).

VoiceOfUnreason
la source
7

Cela dépend de ce que vous entendez par «directement».

Selon l'architecture des microservices, il est parfaitement correct d'avoir des microservices qui invoquent d'autres microservices, soit sur votre propre serveur, soit même sur des serveurs externes, via une interface comme REST.

Ce qui ne va pas, c'est qu'un microservice en appelle un autre en utilisant des invocations de méthode directes; cela ferait des deux microservices une partie du même monolithe.

Mike Nakis
la source
ce n'est pas bien et cela aura de mauvaises conséquences. Voir ma réponse pour plus de détails.
IlliakaillI
@IlliakaillI Je dis que c'est bien "selon l'architecture des microservices". Je ne dis pas que l'architecture des microservices est exempte de conséquences ou qu'aucune amélioration ne peut y être apportée. La question ici est "est-ce que X par le livre, ou non?" et la bonne réponse est que, étant donné la définition correcte de X, c'est par le livre.
Mike Nakis
Existe-t-il un "livre de référence" qui vous explique comment construire une véritable "architecture de microservices"? Les microservices deviennent un mot à la mode de nos jours et de nombreuses personnes ont écrit des livres sur la façon de construire des monolithes au-dessus de REST. Il suffit de regarder ce premier diagramme dans ma réponse, cela n'a pas de sens de construire un système de cette façon. Si vous le faites pour une raison étrange - vous vous trompez définitivement. Tu ferais mieux d'aller avec monolith à la place. Si vous soutenez vos choix de conception en vous référant aveuglément à certains livres (en faisant valoir un argument de l'autorité), ce n'est pas une bonne façon d'aborder la conception de logiciels.
IlliakaillI
5

Ces services devraient-ils pouvoir communiquer directement entre eux? Si c'est le cas, cela ne les rendrait-il pas contraires au concept des microservices?

Le couplage n'est pas un mauvais mot. Chaque application a déjà un certain degré de couplage; les applications qui parlent à vos microservices sont déjà couplées aux microservices, sinon elles ne fonctionneraient pas.

Ce que vous recherchez vraiment avec les microservices, c'est un couplage lâche ; vous pouvez y parvenir en demandant simplement à un microservice d'interroger l'autre via son API publique ou en utilisant un bus d'événements.

En pratique, cependant, un ou plusieurs de vos microservices (peut-être tous) parleront à un magasin de données central comme une base de données SQL. Selon la façon dont vous souhaitez atteindre votre objectif, vous pouvez simplement demander à un microservice de modifier les données de la base de données d'une manière ou d'une autre, que l'autre microservice interrogera pour détecter la modification.

Robert Harvey
la source
3
"Base de données d'intégration" est un contre-modèle bien connu, voir ma réponse pour plus de détails.
IlliakaillI
2

Il semble qu'en parlant de SOA et d'architecture en général, les gens se retrouvent pris dans la sémantique et le jargon. Qu'est-ce qui rend un service "micro"? En fin de compte, c'est un ensemble de caractéristiques qui, quel que soit le «système de notation» que vous utilisez, ne rendent pas le service «non micro». Qu'est-ce que la justice de la Cour suprême a dit au sujet de l'indécence? "Je le saurai quand je le verrai."

Je suis sûr que certaines personnes diront que c'est une non-réponse, mais elles manquent de raison. Les architectures de micro-services visent à éviter plusieurs problèmes, parmi lesquels la question du «couplage serré». Donc, si vous finissez par créer un enchevêtrement de micro-services qui dépendent de trop de détails les uns des autres, vous avez créé un couplage étroit qui - que vous utilisiez un bus de messages pub / sub ou des appels directs - détruit votre capacité à composer de nouvelles solutions à partir des pièces, à reconfigurer des pièces individuelles sans faire tomber l'ensemble du système, etc., etc.

Flickerthing dot com
la source
1

Le client doit-il les appeler directement les uns après les autres pour obtenir les données dont il a besoin pour charger une page Web sur le client?

Ça dépend; cependant, je suggère de fournir des capacités directement utilisables au client et de masquer (encapsuler) les détails de la façon dont les résultats sont assemblés (par exemple via plusieurs micro services).

Si trop de logique est impliquée dans la combinaison des résultats individuels de micro-services par le client, cela peut provoquer par inadvertance une logique métier de se glisser dans le client. Il peut également exposer plus de votre architecture interne au client que vous ne le souhaiteriez, gênant la refactorisation ultérieure des microservices.

Donc, cela signifie qu'avec les microservices, il est parfois utile d'avoir un microservice wrapper qui fournit au client un point de terminaison ayant des abstractions utiles et qui effectue une coordination de niveau supérieur d'autres microservices (peut-être maintenant plus internes).


(De plus, les allers-retours vers le client sont probablement plus chers que vos microservices entre eux.)


Si vous regardez la direction prise par GraphQL, par exemple, vous trouverez des clients émettant des requêtes directement pertinentes à un point de terminaison, qui peuvent ou non être implémentées comme une collection de micrservices. Comme l'architecture des microservices est cachée derrière GraphQL, cela rend l'architecture plus facile à refactoriser et aussi plus conviviale pour le client. Voir, par exemple, https://stackoverflow.com/a/38079681/471129 .

Erik Eidt
la source
1

Le principal objectif des micro-services est de coupler votre application de manière lâche. Par conséquent, les services ne peuvent pas s’appeler. Sinon, il sera couplé étroitement. Mais qu'allons-nous faire si nous avons deux services qui doivent partager des données? La réponse est Message Broker. Ainsi, le service qui obtient les données du client peut partager les données avec le courtier de messages central, puis les services doivent utiliser ces données peuvent les consommer, les transformer et les placer dans son propre stockage de données. Je recommande Kafka car vous pouvez joindre des données de différents sujets à la volée avec Kafka Stream. PS. mieux séparer vos micro-services par fonctionnalité.

Panuwat Anawatmongkhon
la source