Maison  >  Article  >  interface Web  >  Parlons du module Nodejs-cluster et présentons comment l'utiliser.

Parlons du module Nodejs-cluster et présentons comment l'utiliser.

青灯夜游
青灯夜游avant
2021-12-13 18:44:022060parcourir

Cet article vous fera découvrir le module Nodejs-cluster dans node et présentera l'utilisation du module Nodejs-cluster. J'espère qu'il vous sera utile !

Parlons du module Nodejs-cluster et présentons comment l'utiliser.

Parfois, l'intervieweur vous demandera, veuillez me dire comment démarrer plusieurs processus dans nodejs Le module cluster devrait immédiatement apparaître dans votre esprit. Laissez-moi maintenant vous emmener explorer l'utilisation du module cluster.

Utilisation de base

Node.js s'exécute par défaut en un seul processus. Pour les systèmes 32 bits, il peut utiliser jusqu'à 512 Mo de mémoire, et pour les systèmes 64 bits, il peut utiliser jusqu'à 1 Go de mémoire. Pour les ordinateurs équipés de processeurs multicœurs, cela est très inefficace car un seul cœur est en cours d’exécution et les autres cœurs sont inactifs. Le module cluster a été proposé pour résoudre ce problème.

Le module cluster permet la mise en place d'un processus principal et de plusieurs processus de travail, le processus principal surveillant et coordonnant le fonctionnement des processus de travail. Les travailleurs utilisent la communication inter-processus pour échanger des messages. Le module de cluster dispose d'un équilibreur de charge intégré et utilise l'algorithme Round-robin pour coordonner la charge entre les processus de travail. Lors de l'exécution, tous les liens nouvellement établis sont complétés par le processus principal, puis le processus principal attribue la connexion TCP au processus de travail désigné.

var cluster = require('cluster');
var os = require('os');

if (cluster.isMaster){
  for (var i = 0, n = os.cpus().length; i < n; i += 1){
    cluster.fork();
  }
} else {
  http.createServer(function(req, res) {
    res.writeHead(200);
    res.end("hello world\n");
  }).listen(8000);
}

Le code ci-dessus détermine d'abord si le processus actuel est le processus principal (cluster.isMaster). Si tel est le cas, créez plusieurs nouveaux processus de travail en fonction du nombre de cœurs de processeur ; processus, puis dans ce processus, démarrez un programme serveur.

L'un des inconvénients du code ci-dessus est qu'une fois le processus de travail suspendu, le processus principal ne peut pas le savoir. Afin de résoudre ce problème, vous pouvez déployer des fonctions d'écoute pour les événements en ligne et quitter les événements dans le processus principal.

var cluster = require(&#39;cluster&#39;);

if(cluster.isMaster) {
  var numWorkers = require(&#39;os&#39;).cpus().length;
  console.log(&#39;Master cluster setting up &#39; + numWorkers + &#39; workers...&#39;);

  for(var i = 0; i < numWorkers; i++) {
    cluster.fork();
  }

  cluster.on(&#39;online&#39;, function(worker) {
    console.log(&#39;Worker &#39; + worker.process.pid + &#39; is online&#39;);
  });

  cluster.on(&#39;exit&#39;, function(worker, code, signal) {
    console.log(&#39;Worker &#39; + worker.process.pid + &#39; died with code: &#39; + code + &#39;, and signal: &#39; + signal);
    console.log(&#39;Starting a new worker&#39;);
    cluster.fork();
  });
}

Dans le code ci-dessus, une fois que le processus principal écoute l'événement de sortie du processus de travail, il redémarrera un processus de travail. Une fois que le processus de travail est démarré avec succès et peut s'exécuter normalement, un événement en ligne sera émis.

objet travailleur

L'objet travailleur est la valeur de retour de cluster.fork() et représente un processus de travail.

Ses propriétés et méthodes sont les suivantes.

(1) worker.id

worker.id renvoie le numéro de processus unique du travailleur actuel. Ce numéro est également la valeur d'index dans cluster.workers qui pointe vers le processus en cours.

(2) worker.process

Tous les processus de travail sont générés à l'aide de child_process.fork(). L'objet renvoyé par child_process.fork() est enregistré dans worker.process. Grâce à cet attribut, vous pouvez obtenir l'objet de processus où se trouve le travailleur.

(3) worker.send()

Cette méthode est utilisée dans le processus principal pour envoyer des informations au processus enfant.

if (cluster.isMaster) {
  var worker = cluster.fork();
  worker.send(&#39;hi there&#39;);
} else if (cluster.isWorker) {
  process.on(&#39;message&#39;, function(msg) {
    process.send(msg);
  });
}

La fonction du code ci-dessus est que le processus de travail fait écho à chaque message envoyé par le processus principal.

Dans le processus de travail, pour envoyer des messages au processus principal, utilisez process.send(message); pour écouter les messages envoyés par le processus principal, utilisez le code suivant. Le message envoyé par

process.on(&#39;message&#39;, function(message) {
  console.log(message);
});

peut être une chaîne ou un objet JSON. Vous trouverez ci-dessous un exemple d'envoi d'un objet JSON.

worker.send({
  type: &#39;task 1&#39;,
  from: &#39;master&#39;,
  data: {
    // the data that you want to transfer
  }
});

objet cluster.workers

Cet objet est uniquement disponible pour le processus principal et contient tous les processus de travail. La valeur clé de chaque membre est un objet de processus de travail et le nom de clé est l'attribut worker.id du processus de travail.

function eachWorker(callback) {
  for (var id in cluster.workers) {
    callback(cluster.workers[id]);
  }
}
eachWorker(function(worker) {
  worker.send(&#39;big announcement to all workers&#39;);
});

Le code ci-dessus est utilisé pour parcourir tous les processus de travail.

L'événement data du socket actuel peut également utiliser l'attribut id pour identifier le processus de travail.

socket.on(&#39;data&#39;, function(id) {
  var worker = cluster.workers[id];
});

propriétés et méthodes du module cluster

isMaster, la propriété isWorker

isMaster renvoie une valeur booléenne indiquant si le processus actuel est le processus principal. Cet attribut est déterminé par process.env.NODE_UNIQUE_ID Si process.env.NODE_UNIQUE_ID n'est pas défini, cela signifie que le processus est le processus principal. L'attribut

isWorker renvoie une valeur booléenne indiquant si le processus actuel est un processus de travail. C'est exactement la valeur opposée de l'attribut isMaster.

fork()

La méthode fork est utilisée pour créer un nouveau processus de travail et le contexte est copié dans le processus principal. Seul le processus principal peut appeler cette méthode.

Cette méthode renvoie un objet travailleur.

kill()

La méthode kill est utilisée pour terminer le processus de travail. Il peut accepter un paramètre représentant un signal système.

S'il s'agit actuellement du processus principal, il mettra fin au contact avec worker.process, puis enverra la méthode de signal système au processus de travail. S'il s'agit actuellement d'un processus de travail, il mettra fin à la communication avec le processus principal, puis quittera en renvoyant 0.

Dans les versions précédentes, cette méthode était également appelée worker.destroy() .

événement d'écoute

Après que le processus de travail ait appelé la méthode d'écoute, l'événement "écoute" est transmis au serveur du processus puis au processus principal.

La fonction de rappel de cet événement accepte deux paramètres, l'un est l'objet travailleur actuel et l'autre est l'objet adresse, y compris l'URL, le port, le type d'adresse (IPv4, IPv6, socket Unix, UDP) et d'autres informations. Ceci est utile pour les applications Node qui servent plusieurs URL.

Redémarrer le service Node sans interruption

重启服务需要关闭后再启动,利用cluster模块,可以做到先启动一个worker进程,再把原有的所有work进程关闭。这样就能实现不中断地重启Node服务。

首先,主进程向worker进程发出重启信号。

workers[wid].send({type: &#39;shutdown&#39;, from: &#39;master&#39;});

worker进程监听message事件,一旦发现内容是shutdown,就退出。

process.on(&#39;message&#39;, function(message) {
  if(message.type === &#39;shutdown&#39;) {
    process.exit(0);
  }
});

下面是一个关闭所有worker进程的函数。

function restartWorkers() {
  var wid, workerIds = [];
  for(wid in cluster.workers) {
    workerIds.push(wid);
  }

  workerIds.forEach(function(wid) {
    cluster.workers[wid].send({
      text: &#39;shutdown&#39;,
      from: &#39;master&#39;
     });
    setTimeout(function() {
      if(cluster.workers[wid]) {
        cluster.workers[wid].kill(&#39;SIGKILL&#39;);
      }
    }, 5000);
  });
};

PM2模块

PM2模块是cluster模块的一个包装层。它的作用是尽量将cluster模块抽象掉,让用户像使用单进程一样,部署多进程Node应用。

// app.js
var http = require(&#39;http&#39;);

http.createServer(function(req, res) {
  res.writeHead(200);
  res.end("hello world");
}).listen(8080);

用PM2从命令行启动这段代码

$ pm2 start app.js -i 4

上面代码的i参数告诉PM2,这段代码应该在cluster_mode启动,且新建worker进程的数量是4个。如果i参数的值是0,那么当前机器有几个CPU内核,PM2就会启动几个worker进程。

如果一个worker进程由于某种原因挂掉了,会立刻重启该worker进程。

# 重启所有worker进程
$ pm2 reload all

每个worker进程都有一个id,可以用下面的命令查看单个worker进程的详情。

$ pm2 show <worker id>

关闭worker进程的时候,可以部署下面的代码,让worker进程监听shutdown消息。一旦收到这个消息,进行完毕收尾清理工作再关闭

process.on(&#39;message&#39;, function(msg) {
  if (msg === &#39;shutdown&#39;) {
    close_all_connections();
    delete_logs();
    server.close();
    process.exit(0);
  }
});

更多node相关知识,请访问:nodejs 教程!!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer