4

1 秒あたり約 500 ~ 600 リクエストの高負荷サーバーでテスト済み。何時間ものデバッグの後、単純な HTTP サーバーだけになりました。

応答本文がそれよりも大きい場合、たとえば 60k になると、次のエラーが発生することに気付きました。

(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
Trace
    at Socket.EventEmitter.addListener (events.js:160:15)
    at Socket.Readable.on (_stream_readable.js:679:33)
    at Socket.EventEmitter.once (events.js:179:8)
    at TCP.onread (net.js:527:26)

そしてその後、CPUは狂ったように行きました

しかし、まったく同じコードで、応答を 10k のテキストに設定すると、すべてがスムーズに機能しました。変...

誰もこれに遭遇したことがありますか?助けを求める。

これは完全なスクリプトです:

var
cluster = require('cluster'),
numCPUs = require('os').cpus().length;



if(cluster.isMaster){

    for (var i = 0; i < numCPUs; i++) cluster.fork();

    cluster.on("exit", function(worker, code, signal) {
        cluster.fork();
    });

}
else{


    var http = require('http');


    var app = function(req, res){

        res.writeHead(200, {'Content-Type': 'text/html', 'Access-Control-Allow-Origin': '*'});
        res.end( 60k_of_text___or___10k_of_text );

    };


    http.createServer(app).listen(80);


}
4

1 に答える 1

0

現在、すべての文字列は最初に Buffer インスタンスに変換されます。これにより、ガベージ コレクターが要求ごとにクリーンアップするための負荷が大きくなる可能性があります。でアプリケーションを実行し、ファイルを--prof調べると、それが表示される場合があります。v8.logtools/*-tick-processor

これを修正する作業が行われているため、文字列は直接メモリに書き出され、リクエストが完了するとクリーンアップされます。f5e13aeではファイルシステムの書き込み用に実装されていますが、他のケースではまだ実装されていません (実装は見た目よりもはるかに困難です)。

また、文字列をバッファに変換するのは非常にコストがかかります。特にutf8文字列(デフォルト)の場合。可能な場合は、必ず文字列をバッファとして事前にキャッシュして使用してください。スクリプトの例を次に示します。

var http = require('http');
var str = 'a';
for (var i = 0; i < 60000; i++)
  str += 'a';

//str = new Buffer(str, 'binary');

http.createServer(function(req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain',
                      'Access-Control-Allow-Origin': '*'});
  res.end(str);
}).listen(8011, '127.0.0.1');

そして、最初に文字列として渡され、次に永続化されたバッファとして渡されたwrk 'http://127.0.0.1:8011/'サーバーに対して実行した結果を次に示します。str

Running 10s test @ http://127.0.0.1:8011/
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     0.00us    0.00us   0.00us    -nan%
    Req/Sec     0.00      0.00     0.00      -nan%
  8625 requests in 10.00s, 495.01MB read
Requests/sec:    862.44
Transfer/sec:     49.50MB


Running 10s test @ http://127.0.0.1:8011/
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   624.07us  100.77us   4.45ms   99.17%
    Req/Sec     7.98k   729.82     9.00k    57.59%
  158711 requests in 10.00s, 8.90GB read
Requests/sec:  15871.44
Transfer/sec:      0.89GB

少なくとも、渡す文字列にASCII文字のみが含まれていることがわかっている場合はres.end(str)res.end(new Buffer(str, 'binary')). v8::String::WriteOneByteこれは、はるかに高速な方法を使用します。その変更を使用した結果は次のとおりです。

Running 10s test @ http://127.0.0.1:8011/
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   827.55us  540.57us   7.03ms   97.38%
    Req/Sec     6.06k     1.11k    8.00k    85.93%
  121425 requests in 10.00s, 6.81GB read
Requests/sec:  12142.62
Transfer/sec:    696.89MB
于 2013-07-03T19:03:37.393 に答える