Architecture actuelle:
Problème:
Nous avons un flux en deux étapes entre les couches frontend et backend.
Le micro service 2 (MS2) doit valider l'intégrité de I1 car il provient du frontend. Comment éviter une nouvelle requête vers MS1? Quelle est la meilleure approche?
Flux que j'essaie d'optimiser en supprimant les étapes 1.3 et 2.3
Flux 1:
Flux 2:
Approche
Une approche possible consiste à utiliser une requête HTTP B2B entre MS2 et MS1, mais nous dupliquerions la validation dans la première étape. Une autre approche consiste à dupliquer les données de MS1 à MS2. cependant, cela est prohibitif en raison de la quantité de données et de sa nature de volatilité. La duplication ne semble pas être une option viable.
Une solution plus appropriée est à mon avis le frontend d'avoir la responsabilité de récupérer toutes les informations requises par le micro service 1 sur le micro service 2 et de les livrer au micro service 2. Cela évitera toutes ces requêtes HTTP B2B.
Le problème est de savoir comment le micro service 1 peut faire confiance aux informations envoyées par le frontend. Peut-être en utilisant JWT pour signer en quelque sorte les données du micro service 1 et le micro service 2 sera en mesure de vérifier le message.
Remarque Chaque fois que le micro-service 2 a besoin d'informations du micro-service 1, une requête http B2B est effectuée. (La requête HTTP utilise ETAG et Contrôle du cache: max-age ). Comment éviter cela?
Objectif d'architecture
Le microservice 1 a besoin des données du microservice 2 à la demande pour pouvoir conserver MS1_Data et MS2_Data sur la base de données MS1, donc l'approche ASYNC utilisant un courtier ne s'applique pas ici.
Ma question est de savoir s'il existe un modèle de conception, les meilleures pratiques ou un cadre pour permettre ce type de communication poussée.
L'inconvénient de l'architecture actuelle est le nombre de requêtes HTTP B2B qui sont effectuées entre chaque micro-service. Même si j'utilise un mécanisme de contrôle du cache, le temps de réponse de chaque micro-service sera affecté. Le temps de réponse de chaque micro-service est critique. Le but ici est d'archiver une meilleure performance et certains comment utiliser le frontend comme passerelle pour distribuer des données à travers plusieurs micro services mais en utilisant une communication de poussée .
MS2_Data n'est qu'un SID d'entité comme le SID de produit ou SID de fournisseur que le MS1 doit utiliser pour maintenir l'intégrité des données.
Solution possible
L'idée est d'utiliser la passerelle comme un traitement de demande de passerelle api qui mettra en cache une réponse HTTP de MS1 et MS2 et les utilisera comme réponse à MS2 SDK et MS1 SDK. De cette façon, aucune communication (SYNC OR ASYNC) n'est établie directement entre MS1 et MS2 et la duplication des données est également évitée.
Bien sûr, la solution ci-dessus concerne uniquement les UUID/GUID partagés entre les micro-services. Pour les données complètes, un bus d'événements est utilisé pour distribuer les événements et les données sur les microservices de manière asynchrone (modèle de source d'événements).
Inspiration: https://aws.Amazon.com/api-gateway/ et https://getkong.org/
Questions et documentation connexes:
Vérifiez la section Solution possible sur ma question:
L'idée est d'utiliser la passerelle comme un traitement de demande de passerelle api qui mettra en cache une réponse HTTP de MS1 et MS2 et les utilisera comme réponse à MS2 SDK et MS1 SDK. De cette façon, aucune communication (SYNC OR ASYNC) n'est établie directement entre MS1 et MS2 et la duplication des données est également évitée.
Inspiration: https://aws.Amazon.com/api-gateway/ et https://getkong.org/
D'après la question et les commentaires, je comprends que vous essayez de réorganiser les blocs pour améliorer les performances du système. Comme décrit par les diagrammes, vous suggérez qu'au lieu que microservice1 interroge microservice2, la passerelle interroge microservice2, puis interroge microservice1 en lui fournissant les informations de microservice2.
En tant que tel, je ne vois pas comment cela augmenterait considérablement les performances du système, mais plutôt le changement semble simplement déplacer la logique.
Pour remédier à la situation, les performances du microservice2 critique doivent être améliorées. Cela peut être fait en profilant et en optimisant le logiciel microservice2 (mise à l'échelle verticale) et/ou vous pouvez introduire un équilibrage de charge (mise à l'échelle horizontale) et exécuter microservice2 sur plusieurs serveurs. Le modèle de conception à utiliser dans ce cas est modèle d'équilibrage de la charge de service .
Vous pouvez envisager de changer votre mode de synchronisation de communication b2b en mode asynchrone en utilisant un modèle de publication-abonnement. Dans cette situation, le fonctionnement des services sera plus indépendant et vous n'aurez peut-être pas besoin d'effectuer des requêtes b2b tout le temps.
La façon dont vous le rendez plus rapide dans un système distribué est la dénormalisation. Si ms2data change rarement, par ex. vous le lisez plus que le réécrire, vous devez le dupliquer entre les services. En faisant cela, vous réduirez la latence et le couplage temporel. L'aspect de couplage peut être encore plus important que la vitesse dans de nombreuses situations.
Si ms2data est une information sur le produit, alors ms2 doit publier l'événement ProductCreated contenant ms2data sur un bus. Ms1 doit être abonné à cet événement et stocker ms2data dans sa propre base de données. Désormais, chaque fois que ms1 requiert des données ms2, il les lit simplement localement sans avoir à effectuer de requêtes à ms2. C'est ce que signifie le découplage temporel. Lorsque vous suivez ce modèle, votre solution devient plus tolérante aux pannes et l'arrêt de ms2 n'influencera en aucune façon ms1.
Pensez à lire un bonne série d'articles qui décrit les problèmes derrière la communication de synchronisation dans l'architecture des microservices.
Connexes SO questions ici et ici discutant de problèmes assez similaires, pensez à y jeter un œil).
Il est difficile de juger de la viabilité d'une solution sans regarder "à l'intérieur" des boîtes, cependant:
Si la seule chose dont vous vous souciez ici est d'empêcher le frontend de potentiellement altérer les données, vous pouvez créer une sorte de "signature" du paquet de données envoyé par MS2 au frontend et propager la signature à MS1 avec le paquet. La signature peut être un hachage du paquet contenant un numéro pseudo-aléatoire généré de manière déterministe à partir d'une graine partagée par les microservices (afin que MS1 puisse recréer le même numéro pseudo-aléatoire que MS2 sans avoir besoin d'une demande HTTP B2B supplémentaire, puis vérifier l'intégrité du paquet).
La première idée qui me vient à l'esprit est de vérifier si la propriété des données peut être modifiée. Si MS1 doit accéder fréquemment à un sous-ensemble de données de MS2, il PEUT être possible de déplacer la propriété de ce sous-ensemble de MS2 à MS1.
Dans un monde idéal, les microservices devraient être complètement autonomes, chacun avec sa propre couche de persistance et un système de réplication en place. Vous dites qu'un courtier n'est pas une solution viable, alors qu'en est-il d'une couche de données partagée?
J'espère que ça aide!