Node.js は面白そうです、しかし私はなにか見逃しているはずです - Node.jsではありません単一のプロセスとスレッドで実行するように調整された?
それでは、マルチコアCPUとマルチCPUサーバーにどのように対応しますか。結局のところ、可能な限りシングルスレッドサーバーを高速化するのは素晴らしいことですが、高負荷の場合は複数のCPUを使用したいと思います。また、アプリケーションの高速化にも同じことが言えます。今日では、複数のCPUを使用してタスクを並列化する方法が使用されているようです。
Node.jsはこの絵にどのように適合しますか?どういうわけか複数のインスタンスを配布するという考えですか、それとも何ですか。
Node.jsはマルチコアマシンでは絶対に拡張できます。
はい、Node.jsはプロセスあたり1スレッドです。これは非常に慎重な設計上の決定であり、ロックセマンティクスを扱う必要性を排除します。これに同意しないのであれば、マルチスレッドコードをデバッグするのがどれほど難しいか、まだ気付いていないでしょう。 Node.jsプロセスモデルと、それがなぜこのように機能するのか(そしてなぜそれが複数のスレッドをサポートしないのか)のより深い説明については、 my other post を読んでください。
二通り:
V6.0.X以降、Node.jsには そのままクラスタモジュール が含まれるようになりました。これにより、単一のノードで待機できる複数のノードワーカーを簡単に設定できます。港。これは npm で利用できる古いlearnboostの "cluster"モジュールと同じではないことに注意してください。
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
} else {
http.Server(function(req, res) { ... }).listen(8000);
}
労働者は新しい接続を受け入れるために競争し、最も負荷の少ないプロセスが勝つ可能性が最も高いです。それはかなりうまく機能し、マルチコアボックスでスループットをかなりうまくスケールアップすることができます。
複数のコアを気にするのに十分な負荷がある場合は、さらにいくつかのことをしたいと思うでしょう。
Nginx または Apache のようなWebプロキシの背後でNode.jsサービスを実行します - 接続スロットルを実行できるもの(あなたが過負荷状態でボックスを完全に停止させたくないのであれば)URLを書き換え、静的コンテンツを提供し、そして他のサブサービスを代理する。
定期的にあなたのワーカープロセスをリサイクルしてください。長時間実行されているプロセスでは、わずかなメモリリークでも最終的には合計されます。
セットアップログの収集/監視
シモンズ:アロンとクリストファーの間で、別の記事のコメントで議論があります(この記事の執筆時点では、その一番上の記事)。そのいくつかのコメント:
共有ポート:nginx (port 80) --> Node_workers x N (sharing port 3000 w/ Cluster)
vs
個別のポート:nginx (port 80) --> {Node_worker (port 3000), Node_worker (port 3001), Node_worker (port 3002), Node_worker (port 3003) ...}
個々のportsの設定にはおそらく確かにいくつかの利点があります(プロセス間のカップリングが少なくなり、より高度なロードバランシングの決定などができる可能性があります)。ほとんどの人のために働く - 複雑さの選択肢。
1つの方法は、サーバー上でnode.jsの複数のインスタンスを実行してから、それらの前にロードバランサ(できればnginxのような非ブロック化インスタンス)を配置することです。
Ryan Dahlは、この質問に 彼がGoogleで行ったテクニカルトーク で答えています。言い換えれば、「複数のノードプロセスを実行し、それらが通信できるように賢明なものを使用するだけです。たとえば、sendmsg()スタイルIPCや従来のRPCなど)。
手をすぐに汚したい場合は、 spark2 永遠に モジュール。これにより、複数ノードプロセスの生成が簡単になります。ポート共有の設定を処理するので、それぞれが同じポートへの接続を受け付けることができます。また、プロセスが確実に再開された場合に、プロセスが確実に再開されるようにする場合は、自動再起動も可能です。
UPDATE - 10/11/11: Cluster は、マシンごとに複数のノードインスタンスを管理するための優先モジュールになりました。 永遠に も見る価値があります。
clusterモジュールを使うことができます。これをチェック してください 。
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
});
} else {
// Workers can share any TCP connection
// In this case its a HTTP server
http.createServer(function(req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);
}
マルチノードはあなたが持っているかもしれないすべてのコアを利用します。
http://github.com/kriszyp/multi-node をご覧ください。
より簡単なニーズのために、異なるポート番号でノードの複数のコピーを起動し、それらの前にロードバランサーを置くことができます。
上で述べたように、 Cluster はすべてのコアに渡ってあなたのアプリを拡張し、負荷分散します。
のようなものを追加する
cluster.on('exit', function () {
cluster.fork();
});
失敗したワーカーを再起動します。
最近では、多くの人が PM2 を好んでいます。これは、クラスタリングを処理し、 いくつかの優れた監視機能を提供します 。
次に、クラスタリングを実行している複数のマシンの前にNginxまたはHAProxyを追加すると、複数レベルのフェイルオーバーとはるかに高い負荷容量が得られます。
Nodeの将来のバージョンでは、プロセスをフォークしてメッセージを渡すことができるようになるでしょう。Ryanは、ファイルハンドラも共有する方法を見つけたいと述べているので、これは単純なWeb Workerの実装ではありません。
現時点ではこれに対する簡単な解決策はありませんが、それはまだ非常に早い段階であり、nodeは私が今まで見た中で最も速く動いているオープンソースプロジェクトの1つです。
Node JsはあなたのCPUを最大限に活用するためにクラスタリングをサポートしています。あなたがクラスタでそれを実行していないのであれば、おそらくあなたはあなたのハードウェア機能を無駄にしています。
Node.jsでのクラスタリングにより、同じサーバーポートを共有できる別々のプロセスを作成できます。たとえば、ポート3000で1つのHTTPサーバーを実行している場合、それはプロセッサのシングルコアのシングルスレッドで実行されている1つのサーバーです。
以下に示すコードを使用すると、アプリケーションをクラスタ化できます。このコードはNode.jsによって表される公式のコードです。
var cluster = require('cluster');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
Object.keys(cluster.workers).forEach(function(id) {
console.log("I am running with ID : " + cluster.workers[id].process.pid);
});
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
});
} else {
//Do further processing.
}
この記事で完全な チュートリアル を確認してください。
Spark2はSparkをベースにしたもので、現在はメンテナンスされていません。 Cluster はその後継であり、CPUコアごとに1つのワーカープロセスを生成したり、死亡したワーカーを再生成したりするなど、いくつかの優れた機能を備えています。
ここでブロックの新しい子供はLearnBoostの "Up" です。
それは "ゼロダウンタイムリロード"を提供し、さらにすべての世界の最高を提供するために複数のワーカー(デフォルトでCPUの数ですが、それは設定可能です)を作成します。
それは新しいですが、かなり安定しているようです、そして私はそれを私の現在のプロジェクトの1つで楽しく使っています。
私は Node worker を使って私のメインプロセスから簡単な方法でプロセスを実行しています。私たちが公式のやり方でやってくるのを待っている間、とてもうまくいっているようです。
cluster モジュールと os モジュールを組み合わせて使用することで、node.jsアプリケーションを複数のコアで実行できます。あなたが持っているCPUの数を検出します。
たとえば、バックエンドで単純なhttpサーバーを実行するserver
モジュールがあり、それを複数のCPUで実行したいとします。
// Dependencies.
const server = require('./lib/server'); // This is our custom server module.
const cluster = require('cluster');
const os = require('os');
// If we're on the master thread start the forks.
if (cluster.isMaster) {
// Fork the process.
for (let i = 0; i < os.cpus().length; i++) {
cluster.fork();
}
} else {
// If we're not on the master thread start the server.
server.init();
}
それぞれ1つのNodeJSプロセスを実行している複数のボックスの前に、純粋なTCPロードバランサー(HAProxy)を使用して、NodeJSを複数のボックスにスケールアウトすることが可能です。
その後、すべてのインスタンス間で共有する共通の知識がある場合は、中央のRedisストアなどを使用して、すべてのプロセスインスタンスから(たとえばすべてのボックスから)アクセスできます。
Webサービスを、UNIXソケットを待機する複数のスタンドアロンサーバーとして設計することもできます。そのため、データ処理などの機能を別々のプロセスにプッシュできます。
これは、cgiプロセスがビジネスロジックを処理してから、UNIXソケットを介してデータベースにデータをプッシュおよびプルする、ほとんどのスクリプト/データベースWebサーバーアーキテクチャに似ています。
違いは、データ処理がポート上で待機しているノードWebサーバーとして記述されていることです。
それはより複雑ですが、最終的にはマルチコア開発が行かなければならないところです。 Webリクエストごとに複数のコンポーネントを使用するマルチプロセスアーキテクチャ。