0

基本的に Web サービスからのデータをキャッシュする Node.js アプリケーションがあります。また、できるだけ早く処理する必要がある約 500 個のアイテムを受け取るキューもあります。処理されるとは、それらのそれぞれが作成される 1 つの HTTP 要求とその応答がキャッシュされることを表すことを意味します。

現在、ノードのシングル スレッド アーキテクチャは、このシナリオには理想的ではありません。理想的には、キューをできるだけ早く処理するために、5 ~ 10 個の「スレッド」を生成したいと考えています。child_processプロセスをフォークできるモジュールがあると読みましたが、使用したことはありません。このモジュールは役に立ちますか?

誰でもこの問題の解決策を提案できますか?

4

2 に答える 2

2

child_processes は、同じスクリプトまたは別のスクリプトを実行する新しいノード プロセスの単なるフォークです。その API を使用してシステム プロセスを生成することもできますが、ここでは説明しません。

それらは真の nodejs プロセスのように動作します。

大きな大きなマイナス面があります。

ノード プロセスのスポーンには多くの時間とリソースがかかるため、通常は 1 つのノード プロセス内でデータを計算するか、ワーカーの子プロセスをスポーンして作業を通信する方が高速であることに留意する必要があります。ドキュメントでわかるように、child_process との間でデータを送受信できるため、既に生成されている子プロセスに作業を委任できます。

子プロセスは通常、変更しない限り、それを生成したプロセスと同じ stdin と stdout を共有します。ドキュメントを見てください。非常によく文書化されており、操作が簡単です。

child_process ドキュメント

私はワーカーチャイルドを作成したことはありませんが、このような便利なものを作成しました。

if (process.argv.indexOf("child") == -1) {
  process.chdir(module.filename.replace(/\/[^\/]+$/, ""));
  var child;
  var spawn = function () {
    console.log("spawning child process " + new Date());
    child = require("child_process").fork(module.filename, ["child"]);
    child.on("close", function () {
      spawn();
    });
  }
  spawn();

  process.on("exit", function () {
    child.kill();
  });
  return;
}

// child code begins here

var fs = require("fs");

fs.watch(process.argv[1], function () {
  process.exit();
});
于 2013-10-15T20:01:45.950 に答える
0

child_process モジュールは、あなたが望むことをいくらか行います。

唯一の問題は、文字通り新しいプロセスを生成することです。そのため、考慮しなければならないメモリ オーバーヘッドがあります。サブルーチンを同じファイル内で定義するエレガントさが必要であると仮定すると、JavaScript 文字列をコマンドに渡すことができます。node

したがって、これがまさに私たちが行うことです。しかし、最初に、JSON 互換オブジェクトを受け入れる関数と、その関数を新しいスレッドで実行する関数を作成しましょう。

var child_process = require('child_process');

function startThread(data, fn, callback) {
  var fnStr = '(' + fn.toString() + ')(' + JSON.stringify(data) + ');';

  var node = child_process.spawn('node', ['-e', fnStr]);

  var output = [];

  var onData = function (data) {
    output.push(data.toString('utf8').trim());
  };

  node.stdout.on('data', onData);
  node.stderr.on('data', onData);

  node.on('close', function (code) {
    callback(code, output);
  });
}

例として、「ビール 99 本」の歌詞を生成する新しいスレッドを作成します。

startThread({ doFor: '99' }, function (data) {
  var str = '';
  while (data.doFor) {
    str += data.doFor + ' bottles of beer on the wall ' + data.doFor +
    ' bottles of beer. You take one out, toss it around, ';
    data.doFor--;
    str += data.doFor + ' bottles of beer on the wall\n';
  }
  console.log(str.trim());
}, function (code, outputs) {
  console.log(outputs.join(''));
});

残念ながら、他の「スレッド」で使用される関数は、親スレッドの変数にアクセスできません。

また、データは STDOUT および STDERR を介して渡されます。

于 2013-10-15T19:03:01.410 に答える