48 votes

Communication entre deux microservices

Je suis en train de créer un projet avec une architecture microservices. Et j'ai créé deux microservices.

L'un d'eux concerne l'entité produit, l'autre l'entité facture. Ils ont leurs propres points de terminaison et ils sont connectés ensemble avec la passerelle (j'utilise l'architecture microservices de Jhipster).

Le bill-ms doit accéder à la liste des produits. Je me demande comment je peux communiquer entre ces deux ms. J'ai trois approches en tête :

  1. Envoyer une requête depuis bill-ms vers une file d'attente - comme rabbitMQ, pour obtenir ces produits avec ces identifiants depuis product-ms (je ne sais pas quel est le goulot d'étranglement de cette opération).

  2. Envoyer une requête à la passerelle pour le service de produit et obtenir le produit à partir de là (je suis inquiet de la latence en raison de la taille des données entre eux et de cette façon, je ne touche pas la base de données directement, donc je dépend toujours de la passerelle).

  3. Je peux dupliquer les référentiels, les services et les entités dans bill-ms (c'est une façon horrible, et je pense qu'elle brise la règle de l'architecture ms et la maintenance est très difficile).

Si vous avez d'autres approches, j'apprécierais que vous les partagiez avec moi.

Modifier

  1. Maintenant je sais quel est le goulot d'étranglement : disons qu'il y a 3 instances de bill-ms et comment rabbitMQ décide quelle instance répondre ? ou comment dois-je dire à ribbon " donnez-moi l'instance gratuite de bill-ms pour souscrire à la requête de rabbitMQ " pour l'équilibrage des charges.

2 votes

Vous pourriez également reconsidérer les limites de vos services, peut-être que vos services ont un grain trop fin. De même, la duplication n'est pas forcément une mauvaise chose, si vous considérez que vos produits peuvent disparaître ou être modifiés dans leur base de données alors que dans le projet de loi, vous voulez qu'ils restent inchangés pendant longtemps, dans ce cas, je ne considérerais pas cela comme une duplication mais seulement comme le stockage de l'information immuable sur le produit dont votre projet de loi a besoin.

0 votes

"J'utilise l'architecture microservices de Jhipster" JHipster est juste une bibliothèque qui n'a pas sa propre architecture

4 votes

Jhipster n'est pas une bibliothèque, c'est un générateur d'applications qui met en œuvre une architecture de microservices au-dessus de Spring Cloud Netflix.

43voto

Kaj Points 1566

Je ne suis pas sûr que la réponse que je vais donner soit la bonne. Je suis encore en train d'apprendre moi-même Mais je peux vous dire comment j'ai implémenté mes tentatives de microservices

D'abord, j'ai commencé par HTTP microservices basés sur la communication en utilisant ce blog . Cela fonctionne bien, mais le problème est que l'on crée dépendances entre vos services. Service A doit être conscient d'un service B et doit l'appeler directement (via la découverte de services, etc., bien sûr). C'est ce que vous essayez généralement d'éviter lorsque vous développez des microservices.

Une autre approche que j'ai adoptée dernièrement est l'utilisation d'un fichier message bus . C'est en fait la troisième option que vous avez évoquée dans votre question.

J'ai un service A qui stocke des personnes (juste un exemple). Ce que fait le service lorsqu'il crée une nouvelle personne est le suivant : il envoie un message de type event sur un RabbitMQ bus : personCreatedEvent . Si d'autres services sont intéressés par des événements comme celui-ci, ils peuvent s'inscrire pour eux. Ces services intéressés gardent le informations pertinentes qui les intéressent, dans leurs propres datastores.

Avec cette dernière approche, il n'y a pas vraiment de dépendance entre vos services, car ils ne communiquent pas directement entre eux. Service A n'est pas conscient de service B parce que B ne fait qu'envoyer des événements à RabbitMQ au service qui s'intéresse à ces événements et vice versa.

Bien sûr, vous avez des duplications entre les datastores sur le service. Mais cela peut également être profitable, par exemple, le service B n'a pas besoin d'utiliser le même schéma ou le même mécanisme de stockage de données que le service A. Il stocke uniquement les informations pertinentes de la manière qui convient le mieux à ce service.

1 votes

Ce modèle de conception de publication/abonnement est une très bonne approche.

0 votes

Si j'ai bien compris votre suggestion, je n'utiliserai que les attributs de l'entité produit dont j'ai besoin. C'est pourquoi je prévois de créer un DTO pour cela, et l'entité produit est maintenue dans product-ms. Est-ce une bonne approche de garder toutes les données dans un microservice et d'obtenir les données comme DTO de rabbitMQ ? Est-ce que je vous ai bien compris ? @Luxo

0 votes

Si votre bill-ms a besoin d'accéder aux produits. Le product-ms doit publier des événements sur le bus RabbitMQ comme "ProductCreated", contenant le produit lui-même. Puisque le bill-ms est abonné à ces événements, il les recevra et enregistrera les parties des entités (du produit dans cet exemple) dans son propre datastore. @SerhatTR

2voto

jvence Points 101

Avez-vous regardé http://stytex.de/blog/2016/03/25/jhipster3-microservice-tutorial/ Partie 2 : section sur la communication interservices. Elle vous donne un exemple précis de la manière dont elle est réalisée

0voto

sg4j Points 19

Je vais essayer d'ajouter quelques détails à ce scénario pour souligner ce qui peut ou ne peut pas être qualifié d'événement dans le contexte de Product and Biiling. Le MS de facturation n'a besoin de communiquer avec les MS de produits que lorsqu'une commande est passée. La passation d'une commande relèverait principalement d'un MS distinct, disons le MS de commande. Lorsqu'une commande est créée ou passée, elle contient des informations sur les produits en tant qu'éléments de ligne.

La création d'un ordre peut être considérée comme un événement. Lorsque l'événement de création de commande se produit, il peut être poussé vers une file d'attente pour le service de facturation. La file d'attente doit être implémentée comme une file d'attente de travail dans RabbitMQ. De cette façon, plusieurs instances du système de facturation peuvent s'abonner à la même file d'attente, mais elle sera traitée par un seul et unique travailleur. Le RIBBON ne joue aucun rôle dans l'inscription d'un service en tant que Worker à RabbitMQ. Chaque instance s'inscrit à une file d'attente et RabbitMQ décide en RoundRobin quelle instance du service de facturation doit traiter cet événement.

L'obtention de détails sur les produits d'une commande pour le facturier doit être un appel de service à service dont la charge est équilibrée via Ribbon (si c'est ce que vous utilisez). Obtenir les détails d'un produit n'est pas vraiment un événement, passer une commande l'est, d'où la différence.

De même, Gateway doit être utilisé pour exposer vos services Edge. Pour les appels de service à service, il ne serait pas idéal de passer par le service Gateway.

0voto

freemanpolys Points 540

Une option consiste à envoyer une requête au microservice de facturation en utilisant son nom enregistré dans le registre eureka.

0voto

SarfarazJamal Points 1

Vous pouvez utiliser la solution ci-dessous : Microservice A (i.e. UAA-SERVICE), et Microservice B. Le microservice B veut connecter le microservice A et appeler les services avec le client Feign.

1)Ce code pour Microservice B

@AuthorizedFeignClient(name = "UAA-SERVICE")

public interface UaaServiceClient {

@RequestMapping(method = RequestMethod.GET, path = "api/users")
public List<UserDTO> getUserList();

@RequestMapping(method = RequestMethod.PUT, path = "api/user-info")
public String updateUserInfo(@RequestBody UserDTO userDTO);

}

UAA-SERVICE : trouvez ce nom en exécutant des Instances d'Application avec le registre.

2) Dans le Microservice B (application.yml) Augmenter le délai de connexion du client feign------> feindre : client : config : default :
connectTimeout : 10000 readTimeout : 50000 Entrez la description de l'image ici Augmenter le temps de sortie du fil hystrix-------->

hystrix : commande : défaut : exécution : isolation : thread : timeoutInMilliseconds : 60000 shareSecurityContext : true

Entrez la description de l'image ici 3) ajouter @EnableFeignClients dans la classe principale @SpringBootApplication. -------> Cette solution fonctionne bien pour moi.

0 votes

Fournissez des descriptions pertinentes pour les images jointes afin de permettre au lecteur de mieux comprendre ce qu'il va voir.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X