「node.js clusterでHTTPサーバをマルチプロセス化する」の版間の差分

提供: Node.js/JavaScript入門
移動: 案内検索
(ページの作成:「node.jsのclusterを使用してHTTPサーバ(ウェブサーバ)を並列化し、パフォーマンスを上げられます。 '''読み方''' ;cluster:くらす...」)
(相違点なし)

2014年11月30日 (日) 00:28時点における版

node.jsのclusterを使用してHTTPサーバ(ウェブサーバ)を並列化し、パフォーマンスを上げられます。

読み方

cluster
くらすた

概要

node.jsの問題点として、シングルプロセスで処理をしていて、あるリクエストの処理が長くかかる場合、ほかのすべてのリクエストをブロックする可能性があります。httpモジュールで、ウェブサーバを起動したとき、同時に処理できるアクセスは、1つだけなので、処理がつまると、後ろに並んでいるリクエストの待ち行列は、ブロックされた状態になります。

そのような問題を解決するために、並行サーバ(並列)、マルチスレッドモデルなどがあるわけです。 node.jsでは、この問題に対処するいくつかの方法がありますが、ここでは、clusterを用いた例を示します。

clusterは、マルチコアを活かすためのものです。並行サーバは、コア数以上は実際に動作しないようで、コアが合計2個しかなければ、コア数より多くfork()したとしても、2個分のプロセスしか仕事をしません。

clusterの考え方は、伝統的なUnixプログラミングのforkモデルと同じと捉えて差し支えありません。

cluster.js で示すコードでは、node で起動されたプログラム(親)は、コア数だけ fork を行い、子プロセスがHTTPサーバを起動し、リクエストを処理します。

Unixのfork()と異なるのは、Unixのforkは、forkを呼び出した直後のプログラムが親プロセスと子プロセスで実行されますが、node.jsのclusterの場合は、forkを実行すると、同じプログラムが最初から起動されます。

親プロセスかどうかの判断は、 cluster.isMaster を参照し、真であれば、親と判断します。

ソースコード

cluster.js

/*
 * cluster.js
 * Copyright (C) 2014 kaoru <kaoru@bsd>
 */
var cluster = require('cluster');
var http = require('http');
 
var numCPUs = require('os').cpus().length;
 
var port = 8080;
var max_server = numCPUs; // max server
if (cluster.isMaster) {
        console.log ('master');
 
        for ( var i = 0 ; i < max_server ; ++i) {
                cluster.fork();
        }
 
        cluster.on('exit', function(worker, code, signal) {
                console.log('worker ' + worker.process.pid + ' died');
        });
 
} else {
        console.log("worker");
        var server = http.createServer(function(req, res){
                res.writeHead(200);
                res.end('Hello World');
        }).listen(port);
 
}

実行例

node cluster.js

ベンチマーク

node.jsによるHTTPサーバの作り方の簡単なHTTPサーバとcluster.jsを ab でベンチマークしました。 Hello World レベルのプログラムのベンチマークです。10000 リクエストを並列30でベンチマークした場合です。

ab -n 10000 -c 30 http://localhost:8080/

ベンチマークの結果は、平行サーバは、 2.3 秒、非平行サーバは 3.1秒と、ほんのすこしだけ、パフォーマンスが上がっていることが確認できました。

コア数 2 の並行サーバ

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      30
Time taken for tests:   2.323 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      870000 bytes
HTML transferred:       120000 bytes
Requests per second:    4304.82 [#/sec] (mean)
Time per request:       6.969 [ms] (mean)
Time per request:       0.232 [ms] (mean, across all concurrent requests)
Transfer rate:          365.74 [Kbytes/sec] received

非平行サーバ

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      30
Time taken for tests:   3.175 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      1130000 bytes
HTML transferred:       120000 bytes
Requests per second:    3150.08 [#/sec] (mean)
Time per request:       9.524 [ms] (mean)
Time per request:       0.317 [ms] (mean, across all concurrent requests)
Transfer rate:          347.62 [Kbytes/sec] received

関連項目