Il s'agit d'une continuation de l'article " Nous écrivons le premier microservice sur Node.js avec communication via RabbitMQ ", qui a été bien accueilli par les utilisateurs du Habr.
Dans cet article, je parlerai de la façon de communiquer correctement entre les microservices afin que les microservices restent isolés.
Comment ne pas le faire
Pourquoi avez-vous besoin de communiquer entre microservices? Utilisez une seule base de données, lisez à partir de là ce que vous voulez - quelque chose d'affaires!
Non, tu ne peux pas faire ça. Le concept des microservices est qu'ils sont isolés les uns des autres, personne ne sait rien de quiconque (pratiquement). Très probablement, à l'avenir, lorsque le système commencera à se développer, vous voudrez étendre les fonctionnalités et vous devrez communiquer entre les microservices: par exemple, un utilisateur a acheté un produit, vous devez donc envoyer une notification de vente au vendeur.
Avantages de l'isolation
Fiabilité
Supposons qu'il existe une application monolithique dans laquelle il existe plusieurs contrôleurs:
- Les produits
- Remises
- Le blog
- Les utilisateurs
Un beau jour, notre base de données tombe en panne: nous ne pouvons plus obtenir de produits, pas de remises, pas de billets de blog, pas d'utilisateurs. Le site est complètement indisponible, les clients ne peuvent pas se connecter, l'entreprise perd des bénéfices.
Que se passera-t-il dans l'architecture de microservices?
Dans un autre univers, le même jour que la base de données des microservices des utilisateurs tombe, elle devient inaccessible: les utilisateurs ne peuvent pas se déconnecter, s'inscrire et se connecter. Il semblerait que tout va mal et que l’entreprise perd également des bénéfices, mais non: les acheteurs potentiels peuvent consulter les produits disponibles, lire le blog de l’entreprise et trouver des remises.
Étant donné que chaque microservice possède sa propre base de données, les effets secondaires deviennent beaucoup moins importants.
C'est ce qu'on appelle la dégradation progressive .
Abstraction
Dans une grande application, il est très difficile de se concentrer sur une seule tâche, car la modification d'un petit middleware peut casser une sorte de contrôleur. Vous voulez utiliser le nouveau client pour redis - non, vous ne pouvez pas, ce contrôleur que nous avons écrit il y a trois ans utilise la version 0.1.0. Vous voulez enfin profiter des nouvelles fonctionnalités de Node.js 10? Ou peut-être 12? Désolé, mais le monolithe utilise la version 6.
Comment communiquer
Depuis que nous avons commencé à parler de l'exemple "un utilisateur a acheté un produit, nous envoyons un avis de vente au vendeur", puis nous allons le mettre en œuvre.
Le schéma est le suivant:
- L'utilisateur envoie une demande au marché des microservices pour acheter des choses sur le lien / marché / acheter /: id
- Le drapeau est écrit dans la base de données que le produit est vendu
- Depuis le marché des microservices, une demande est envoyée aux notifications de microservices, auxquelles les clients sont connectés via WebSocket
- Les notifications de microservices envoient un message au vendeur sur la vente de choses
Installer MicroMQ
$ npm i micromq@1 -S
Écrire une passerelle
const Gateway = require('micromq/gateway');
Notre passerelle se compose d'un seul point de terminaison, mais cela suffit par exemple pour la formation.
Rédaction d'une notification de microservice
const MicroMQ = require('micromq'); const WebSocket = require('ws');
Ici, nous élevons le serveur de socket Web et le microservice en même temps pour recevoir des demandes pour les sockets Web et RabbitMQ.
Le schéma est le suivant:
- Un utilisateur se connecte à notre serveur de socket Web
- L'utilisateur est autorisé en envoyant un événement d'
authorize
avec son userId à l'intérieur - Nous gardons la connexion de l'utilisateur afin que vous puissiez lui envoyer des notifications à l'avenir
- Un événement arrive sur RabbitMQ dont vous devez envoyer une notification à l'utilisateur
- Vérification de la validité des données entrantes
- Obtenir une connexion utilisateur
- Envoyer une notification
Écrire un marché de microservices
const MicroMQ = require('micromq'); const { Items } = require('./api/mongodb');
Le schéma est le suivant:
- Nous recevons une demande de l'utilisateur pour l'achat d'un article
- Nous recherchons l'article avec le bon identifiant et nous assurons qu'il n'est pas encore vendu
- Marquer l'article comme vendu
- Nous envoyons une notification au vendeur sur la vente en arrière-plan
- Nous répondons au client
Vérifier
- Nous démarrons 3 processus
- Nous enverrons POST / market / buy / 1
- Nous obtenons la réponse
{ ok: true }
- Le vendeur reçoit une notification
$ PORT=9000 node ./src/gateway.js $ PORT=9001 node ./src/notifications.js $ MONGODB_URL=mongodb://localhost:27017/my-super-microservice node ./src/market.js
