nodejsでclusterを作成します.

6413 ワード

概要
前の文章の中で、私達はウォーカーを通すことができると述べました.threadsは新しいスレッドを作成します.child_を使うことができます.プロcessは新しいサブルーチンを作成します.本論文では、nodejsのクラスタclusterを作成する方法を紹介します.
clusterクラスタ
私たちは、nodejsのevent loopまたはイベント応答プロセッサがシングルスレッドであることを知っていますが、現在のCPUは基本的にマルチコアであり、現代CPUのマルチコアの特性を十分に利用するために、clusterを作成して、複数のサブルーチンを同じサーバのポートを共有することができます.
つまり、clusterを通じて、同じポートの要求を複数のサブルーチンで処理することができます.
まず簡単なhttp serverでclusterを使った例を見てください.
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  console.log(`    ${process.pid}     `);

  //       。
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`     ${worker.process.pid}    `);
  });
} else {
  //            TCP   。
  //      ,     HTTP    。
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('    
'); }).listen(8000); console.log(` ${process.pid} `); }
cluster詳細
clusterモジュールはlib/cluster.jsから生まれました.私たちはcluster.forkを通じてサブプロセスを作成して、メインプロセスの要求を処理します.
clusterの中のイベント
clusterはevents.EventEmitterから継承されていますので、clusterはイベントを送信して受信することができます.
clusterは7のイベントをサポートします.それぞれdisconnect、exit、fork、listening、message、オンラインとsetupです.
disconnectを説明する前に、まずIPCという概念を紹介します.IPCのフルネームはInter-Parocess Communicationで、つまりプロセス間通信です.
IPCは、主にメインプロセスとサブルーチンとの間の通信を行うために使用される.作成後に作業プロセスが自動的にメインプロセスに接続されます.「disconnect」イベントがトリガされた時に接続が切断されます.
disconnectを触発する原因はいろいろあります.worker.disconnectを自主的に呼び出してもいいです.仕事のプロセスが終了したり、killに落とされたりします.
cluster.on('disconnect', (worker) => {
  console.log(`     #${worker.id}      `);
});
exitイベントは、どの作業プロセスがオフになった時にトリガされますか?一般的に、clusterの中のプロセスが異常に終了したかどうかを監視するために使用されます.終了したら、cluster.forkを使って新しいプロセスを作成して、要求を処理するために十分なプロセスがあることを保証します.
cluster.on('exit', (worker, code, signal) => {
  console.log('     %d    (%s).    ...',
              worker.process.pid, signal || code);
  cluster.fork();
});
forkイベントは、cluster.forkメソッドを呼び出したときにトリガされます.
const timeouts = [];
function errorMsg() {
  console.error('    ');
}

cluster.on('fork', (worker) => {
  timeouts[worker.id] = setTimeout(errorMsg, 2000);
});
メインプロセスとワークプロセスのlisteningイベントは、ワークプロセスがlistenメソッドを呼び出したときにトリガされます.
cluster.on('listening', (worker, address) => {
  console.log(
    `         ${address.address}:${address.port}`);
});
このうちウォーカーはワークスレッドを表し、addressにはaddress、port、address Typeの3つの属性が含まれています.addressTypeには4つのオプションがあります.
  • (TCPv 4)
  • (TCPv 6)
  • -1(Unixドメインsocket)
  • 'up 4'or'udp 6'(UDP v 4またはv 6)
  • メッセージイベントは、メインプロセスがサブプロセスから送信されたメッセージを受信したときにトリガされる.
    メインプロセスがワークプロセスを生成するとforkがトリガされ、作業が実行されるとオンラインが起動されます.
    setupMasterメソッドが呼び出されると、setupイベントが発生します.
    clusterの中の方法
    clusterの三つの方法はdisconnect、forkとsetupMasterです.
    cluster.disconnect([callback])
    clusterのdisconnectメソッドを呼び出して、実際にはclusterの各ワーカーでdisconnectメソッドを呼び出します.これによりworkerとメインプロセスとの接続が切断されます.
    すべてのワーカーが接続を切断した後、calbackを実行します.
    cluster.fork([env])
    forkメソッドは、メインプロセスから新しいサブプロセスを作成します.envはプロセス環境変数に追加するキーのペアです.
    forkはcluster.Workカーオブジェクトに戻ります.作業プロセスを表します.
    最後の方法はセットマスターです.
    cluster.setupMaster([settings])
    デフォルトでは、clusterはfork方式で子プロセスを作成しますが、setupMasterによってこの挙動を変えることができます.settings変数を設定することで、後のfork子プロセスの挙動を変えることができます.
    セットメニューの例を見ます.
    const cluster = require('cluster');
    cluster.setupMaster({
      exec: 'worker.js',
      args: ['--use', 'https'],
      silent: true
    });
    cluster.fork(); // https     
    cluster.setupMaster({
      exec: 'worker.js',
      args: ['--use', 'http']
    });
    cluster.fork(); // http     
    clusterのプロパティ
    clusterオブジェクトを通して、isMasterとisWorkerでプロセスがメインかどうかを判断できます.
    現在の作業中のオブジェクトの参照はワーカーによって取得できます.
    const cluster = require('cluster');
    
    if (cluster.isMaster) {
      console.log('     ');
      cluster.fork();
      cluster.fork();
    } else if (cluster.isWorker) {
      console.log(`       #${cluster.worker.id}`);
    }
    ワーカーを通じてアクティブな作業の対象を遍歴することができます.
    //         。
    function eachWorker(callback) {
      for (const id in cluster.workers) {
        callback(cluster.workers[id]);
      }
    }
    eachWorker((worker) => {
      worker.send('        ');
    });
    各ウォーカーには、このウォーカーを特定するためのid番号があります.
    clusterの中のウォーカー
    ワーカー類には、作業プロセスに関するすべての公共情報と方法が含まれています.cluster.forkが出てくるのはworkオブジェクトです.
    ウォーカーのイベントはclusterと似ています.6つのイベントをサポートします.disconnect、error、exit、listening、message、オンラインです.
    workerには三つの属性が含まれています.それぞれid、process、exitedAfter Disconnectです.
    この中のidはワーカーの唯一のマークです.
    ウォーカーの中のプロcessは、実はChildProcessの対象です.process.fork()を作成しました.
    workerでは、processはグローバル変数に属しているので、私たちは直接workerでprocessを使ってメッセージを送ることができます.
    exitedAfter Disconnectは.kill()または.disconnect()によって仕事が終了したら、値はtrueであると表しています.他の方法で終了したら、戻り値はfalseです.作業プロセスが終了していない場合はundefinedとなります.
    我々は、ウォーカー.exitedAfter Disconnectを通じて、自発的に終了するか、それとも受動的に終了するかを区別できます.メインプロセスはこの値に基づいて作業プロセスを再生成するかどうかを決定できます.
    cluster.on('exit', (worker, code, signal) => {
      if (worker.exitedAfterDisconnect === true) {
        console.log('      ,    ');
      }
    });
    
    //       。
    worker.kill();
    ウォーカーはまた6つの方法をサポートしています.それぞれ:send、kill、destroy、disconnect、isConneced、isDeadです.
    ここでは主にsend方法を説明してメッセージを送ります.
    worker.send(message[, sendHandle[, options]][, callback])
    send方法とchild_が見られます.processの中のsend方法のパラメータは実はとても似ています.本質的には、worker.sendは、メインプロセスにおいて、特定の作業プロセスにメッセージを送信する.ChildProcess.send()に相当します.作業中にメインプロセスにメッセージを送ります.プロcess.sendに相当します.
    if (cluster.isMaster) {
      const worker = cluster.fork();
      worker.send('  ');
    
    } else if (cluster.isWorker) {
      process.on('message', (msg) => {
        process.send(msg);
      });
    }
    上記の例では、メインプロセスであれば、worker.sendを使用してメッセージを送信することができる.一方、サブプロセスでは、メッセージはワーカー内のグローバル変数processを使用して送信することができる.
    締め括りをつける
    clusterを使って、マルチコアCPUの利点を十分に活用できます.実際のプロジェクトに応用してほしいです.
    本文の作者:flydeanプログラムのあれらの事
    本論文のリンク:http://www.flydean.com/nodejs-cluster/
    flydeanのブログ
    私の公衆番号に注目してください.「プログラムに関すること」を最も分かりやすく解読し、最も深い商品、最も簡潔な教程、多くのあなたの知らない小さな技術などを発見してください.