Heim >Web-Frontend >js-Tutorial >Lassen Sie uns über das Nodejs-Cluster-Modul sprechen und seine Verwendung vorstellen.

Lassen Sie uns über das Nodejs-Cluster-Modul sprechen und seine Verwendung vorstellen.

青灯夜游
青灯夜游nach vorne
2021-12-13 18:44:022137Durchsuche

Dieser Artikel führt Sie durch das Nodejs-Cluster-Modul in node und stellt die Verwendung des Nodejs-Cluster-Moduls vor. Ich hoffe, er wird Ihnen hilfreich sein!

Lassen Sie uns über das Nodejs-Cluster-Modul sprechen und seine Verwendung vorstellen.

Manchmal wird der Interviewer Sie fragen, wie Sie mehrere Prozesse in nodejs starten können. Das Cluster-Modul sollte Ihnen jetzt sofort in den Sinn kommen, um die Verwendung des Cluster-Moduls zu erkunden.

Grundlegende Verwendung

Node.js wird standardmäßig in einem einzigen Prozess ausgeführt. Bei 32-Bit-Systemen kann es bis zu 512 MB Speicher und bei 64-Bit-Systemen bis zu 1 GB Speicher verwenden. Bei Computern mit Multi-Core-CPUs ist dies sehr ineffizient, da nur ein Kern läuft und die anderen Kerne im Leerlauf sind. Zur Lösung dieses Problems wurde das Clustermodul vorgeschlagen.

Das Cluster-Modul ermöglicht die Einrichtung eines Hauptprozesses und mehrerer Worker-Prozesse, wobei der Hauptprozess die Ausführung der Worker-Prozesse überwacht und koordiniert. Worker nutzen die prozessübergreifende Kommunikation, um Nachrichten auszutauschen. Das Clustermodul verfügt über einen integrierten Load Balancer und verwendet den Round-Robin-Algorithmus, um die Last zwischen Worker-Prozessen zu koordinieren. Bei der Ausführung werden alle neu eingerichteten Verbindungen vom Hauptprozess abgeschlossen, und dann weist der Hauptprozess die TCP-Verbindung dem angegebenen Arbeitsprozess zu.

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);
}

Der obige Code bestimmt zunächst, ob der aktuelle Prozess der Hauptprozess ist (cluster.isMaster). Wenn ja, erstellen Sie mehrere neue Worker-Prozesse entsprechend der Anzahl der CPU-Kerne Prozess, dann in diesem Prozess Starten Sie ein Serverprogramm.

Ein Nachteil des obigen Codes besteht darin, dass der Hauptprozess nichts davon wissen kann, sobald der Arbeitsprozess hängt. Um dieses Problem zu lösen, können Sie im Hauptprozess Überwachungsfunktionen für Online-Ereignisse und Exit-Ereignisse bereitstellen.

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();
  });
}

Sobald der Hauptprozess im obigen Code auf das Exit-Ereignis des Arbeitsprozesses lauscht, startet er einen Arbeitsprozess neu. Sobald der Arbeitsprozess erfolgreich gestartet wurde und normal ausgeführt werden kann, wird ein Online-Ereignis ausgegeben.

Worker-Objekt

Das Worker-Objekt ist der Rückgabewert von cluster.fork() und stellt einen Worker-Prozess dar.

Seine Eigenschaften und Methoden sind wie folgt.

(1) worker.id

worker.id gibt die eindeutige Prozessnummer des aktuellen Arbeiters zurück. Diese Zahl ist auch der Indexwert in „cluster.workers“, der auf den aktuellen Prozess verweist.

(2) worker.process

Alle Worker-Prozesse werden mit child_process.fork() generiert. Das von child_process.fork() zurückgegebene Objekt wird in worker.process gespeichert. Über dieses Attribut können Sie das Prozessobjekt abrufen, in dem sich der Worker befindet.

(3) worker.send()

Diese Methode wird im Hauptprozess verwendet, um Informationen an den untergeordneten Prozess zu senden.

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);
  });
}

Die Funktion des obigen Codes besteht darin, dass der Arbeitsprozess jede vom Hauptprozess gesendete Nachricht wiedergibt.

Um im Arbeitsprozess Nachrichten an den Hauptprozess zu senden, verwenden Sie „process.send(message)“. Um die vom Hauptprozess gesendeten Nachrichten abzuhören, verwenden Sie den folgenden Code. Die von

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

gesendete Nachricht kann eine Zeichenfolge oder ein JSON-Objekt sein. Unten finden Sie ein Beispiel für das Senden eines JSON-Objekts.

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

cluster.workers-Objekt

Dieses Objekt ist nur für den Hauptprozess verfügbar und enthält alle Worker-Prozesse. Der Schlüsselwert jedes Mitglieds ist ein Arbeitsprozessobjekt, und der Schlüsselname ist das Attribut worker.id des Arbeitsprozesses.

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;);
});

Der obige Code wird verwendet, um alle Arbeitsprozesse zu durchlaufen.

Das Datenereignis des aktuellen Sockets kann auch das ID-Attribut verwenden, um den Arbeitsprozess zu identifizieren.

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

Cluster-Moduleigenschaften und -Methoden

isMaster, isWorker

isMaster-Eigenschaft gibt einen booleschen Wert zurück, der angibt, ob der aktuelle Prozess der Hauptprozess ist. Dieses Attribut wird durch Process.env.NODE_UNIQUE_ID bestimmt. Wenn Process.env.NODE_UNIQUE_ID nicht definiert ist, bedeutet dies, dass der Prozess der Hauptprozess ist. Das Attribut

isWorker gibt einen booleschen Wert zurück, der angibt, ob der aktuelle Prozess ein Arbeitsprozess ist. Es ist genau der entgegengesetzte Wert des isMaster-Attributs.

fork()

Die Fork-Methode wird zum Erstellen eines neuen Arbeitsprozesses verwendet und der Kontext wird in den Hauptprozess kopiert. Nur der Hauptprozess kann diese Methode aufrufen.

Diese Methode gibt ein Worker-Objekt zurück.

kill()

Die Kill-Methode wird verwendet, um den Arbeitsprozess zu beenden. Es kann einen Parameter akzeptieren, der ein Systemsignal darstellt.

Wenn es sich derzeit um den Hauptprozess handelt, wird der Kontakt mit worker.process beendet und dann die Systemsignalmethode an den Worker-Prozess gesendet. Wenn es sich derzeit um einen Arbeitsprozess handelt, beendet er die Kommunikation mit dem Hauptprozess, beendet ihn dann und gibt 0 zurück.

In früheren Versionen wurde diese Methode auch worker.destroy() genannt.

Listening-Ereignis

Nachdem der Arbeitsprozess die Listening-Methode aufgerufen hat, wird das „Listening“-Ereignis an den Server des Prozesses und dann an den Hauptprozess übertragen.

Die Rückruffunktion dieses Ereignisses akzeptiert zwei Parameter, einer ist das aktuelle Worker-Objekt und der andere ist das Adressobjekt, einschließlich URL, Port, Adresstyp (IPv4, IPv6, Unix-Socket, UDP) und anderer Informationen. Dies ist nützlich für Node-Anwendungen, die mehrere URLs bereitstellen.

Knotendienst ohne Unterbrechung neu starten

重启服务需要关闭后再启动,利用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 教程!!

Das obige ist der detaillierte Inhalt vonLassen Sie uns über das Nodejs-Cluster-Modul sprechen und seine Verwendung vorstellen.. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen