assemblee-virtuelle / assemblee-virtuelle/semapps

le clustering de tous les services n'est pas viable

Open
#902 12 comments 0 reactions 2 assignees Claimed by @srosset81 View on GitHub
bug
Dominant language
TypeScript
Stars
103
Forks
14
Avg merge
1m
Merged PRs (30d)
2

Description

Je viens de me rendre compte que dans la branche `next` le middleware est lancé avec `moleculer-runner` et notamment l'option `--instances=max` qui va creer autant de `node` moleculer qu'il y a de core/CPU sur la machine.

le clustering dans nodejs est bien connu, et fonctionne plutot bien. Avec `pm2` par exemple, on peut ecrire un logiciel qui ecoute sur le port 80, et puis le lancer en mode cluster, ce qui va creer autant de processus qu'il y a de cores, chacun executant le meme code. Et dans ce cas, nodejs va load-balancer les connections entrante sur le port 80, et les envoyer sur le processus de son choix, de maniere aleatoire (ou round robin, je ne sais plus) enfin peu importe. C'est load balancé.

Avec Moleculer, on peut aussi loadbalancer, grace au moleculer-runner, mais c'est un peu "bourin".

Explication:

Moleculer fonctionne avec des `nodes`. Un `node` est en fait un processus qui tourne sur une machine. Il est donc possible d'avoir plusieurs nodes qui tourne en parallel sur la meme machine, ou bien, sur differentes machines et reliées en reseau, ou les deux.

Par defaut, quand on lance moleculer, il n'y a qu'un seul `node` qui tourne, et tous les services tournent a l'interieur de ce `node`. on le sait, nodejs fonctionne avec une pompe a message, donc tout passe par des messages, qui declenchent des actions. A l'interieur du `node`, les services sont reliés au `node` par le `ServiceBroker`. C'est la qu'on configure sur quel `node` le service doit tourner. Par defaut, tous les services tournent sur le même `node` et communique entre eux par le broker, qui représente la _pompe à messages._ Ce dernier a besoin d'un `transport` pour achemenr les messages d'un service à un autre, notamment lorsque les services tournent sur des noeuds differents. Lorsque que les services sont sur le meme noeud, les messages sont échangés de maniere locale, en fait, en mémoire vive a l'interieur du processus. Cést le transport par defaut du broker par defaut.

Quand on commence à faire une architecture avec plusieurs `nodes`, il devient necessaire de configurer le transport du broker, sinon les neouds sont isolés.

Par defaut, les services preferent parler avec les autres services qui sont locaux. Si webacl envoie un message a triplestore, et que le broker voit que ces deux services tournent en local sur le meme `node` alors il ne va pas chercher plus loin, il va contacter le service local.

Normalement, quand on commence a penser a creer une architecture a plusieurs nodes, c'est soit qu'on veut profiter des multi-cores, soit qu'on a plusieures machines. On identifie les services qui sont le plus demandés et qui consomment le plus de CPU, et on ajoute donc des `nodes` avec des copies de ces services qui tournent dessus.

On n'est pas obligés de paralléliser tous les services.

APIGateway c'est plutot interessant de le mettre en cluster, c ést sur, car on va pouvoir accepter plus de connections.

Mais les autres services doivent etre etudiés un a un, pour savoir lequel doit etre parallelisé.

Le mode cluster est transparent, car tout fonctionne avec des actions et des messages, meme quand on reste en local.

Mais il faut quand meme bien dire quelque part combien de `nodes` on veut, et quels services doivent tourner dessus.
[Voir la doc ici.](https://moleculer.services/docs/0.14/clustering.html)

Avec le `moleculer-runner` ce sont TOUS les services qui sont clusterisés !

Ce n'est vraiment pas optimal.
En plus, comme aucun transport n'a été configuré dans `moleculer.config.js` et bien chaque `node` fonctionne en vase clos !
Chaque node a son propre service `API gateway` et une copie de tous les autres services, qui ne peuvent discuter qu'avec les services locaux (car pas de transport).

Ca me parait bien trop lourd. et ca cause des problemes.

Notamment pour `webAcl`et `fuseki-admin` qui sont des services avec de la logique dans la function `started()`. fuseki-admin initialize le dataset, et webacl cree le groupe super admin.
on voit bien que lorsqu'on lance le middleware en production, pour la premiere fois, ca ne marche pas, sur une machine avec plusieurs cores, car plusieurs `nodes` veulent créer le dataset en meme temps, et la meme chose se passe au redemarre, pour le groupe super admin.

Il me semble que ces deux services devraient etre des singletons.

Surement d'autres aussi.

Dans ce cas, c'est a nous de creer des commandes differentes pour des `nodes`differents. dans package.json par exemple, on pourrait avoir `start-cluster` et `start-singleton` qui auraient des parametres differents notamment une liste de services differentes.
```
"start-cluster": "moleculer-runner --instances=max cluster-services",
"start-singleton": "moleculer-runner singleton-services",
```
dans le dossier `singleton-services` on mettrait au moins webacl et fuseki-admin. et les autres dans `cluster-services`.

puis, bien evidemment, il devient indispensable de mettre une config de transport dans `moleculer.config.js` sinon les services clusterisés ne pourront pas avoir acces aux services webacl et fuseki-admin, et vis versa.

enfin, on ajouterait 2 services dans le docker-compose. Un service pour les cluster qui lancera `start-cluster`, un service pour les singleton qui lancera `start-singleton`, et aussi, il faudrait rajouter le service de transport (je conseille NATS).

Voila.

On peut aussi se dire que tout ca est bien trop compliqué, et enlever le `--instances=max` de la commande `start` et tout sera regler.
Mais je pense que Seb a du avoir besoin de paralleliser des requetes sparql a un moment.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.