Web サーバー (Cherokee) と expressjs Web サイトの間のパフォーマンスのボトルネックを特定するのに非常に苦労しています。
POST トラフィックの量が増えているため、時々パフォーマンスの問題が発生し始めています。そこで、Web サイトの 1、2、3、4 つのインスタンスの限界点を確認するテストを設計しましたが、パフォーマンスの低下にショックを受けました (1 秒あたり 5 ではうまく機能し、1 秒あたり 10 では非常に貧弱です)。
私のパフォーマンス ログによると、完全なリクエストの開始から終了までの所要時間は 1000 ~ 4000 ミリ秒で始まり、しばらくすると直線的な傾向で増加し始めるため、約 5 分後にリクエストは 40,000 ~ 60,000 ミリ秒かかります。リクエストの開始から終了までの Expressjs Web サイト レコードのパフォーマンス ログには、100 ~ 400 ミリ秒かかります (ほとんどの場合、この時間の 90 ~ 390 ミリ秒は、Java API の応答の待機に費やされます)。
接続プーリング/最大ソケットを調査しましたが、エクスプレスを使用してこれを構成する方法がわかりません。また、トラフィックが増え続けるにつれて、Web サイトのパフォーマンスが低下するたびに熱を感じ始めています。
現在、私には 2 つの仮説があります。1. ストレス テストのコードに本当に問題がある。2. ストレス テスト アプリから、または Expressjs 内でリクエストを送信するときに、小さな接続プールがあります。
上記のいずれかに該当する場合、これらの問題を解決する方法がわかりません。
-- ストレステストアプリ --
/*
* POST stress testing
*/
var rest = require( "restler");
var u = require( "../underscore")._;
var uuid = require( "node-guid" );
var fs = require( "fs" );
var quoteContent = fs.readFileSync( __dirname + "/data/quoteList.json" );
var quotes = JSON.parse( quoteContent ).quotes;
var feedListContent = fs.readFileSync( __dirname + "/data/feedList.json" );
var feeds = JSON.parse( feedListContent ).feeds;
var feedLength = feeds.length;
var experiment = { "users": 2, "frequency": 1000 };
// Clear memory out bit
quoteContent = null;
feedListContent = null;
console.log("Concurrent users:", experiment.users);
console.log("Every :", (experiment.frequency / 1000) + " seconds" );
setInterval(
function()
{
var rndQuote;
for(i=0;i<experiment.users;i++)
{
delayPost( (experiment.frequency) / (experiment.users + 1) );
}
}
, experiment.frequency);
function delayPost( delay )
{
setTimeout(
function()
{
rndQuote = getRandomQuote();
postToRandomFeed( rndQuote );
}
, delay );
}
function getRandomQuote()
{
var n = Math.floor( Math.random() * feedLength );
return quotes[n];
}
function postToRandomFeed( theQuote )
{
var n = Math.floor( Math.random() * feedLength );
var feed = feeds[n];
var kloudId = feed.kloudId
, feedId = feed._id
, uid = feed.owner["$oid"]
, url = "quote://" + uuid.new() // Generate random URL
, quote = theQuote.quote
, author = theQuote.author;
var data = { "url" : url, "title": quote, "text": quote, "tags": [author], "feeds": [ feedId ] }
, postTo = [ "http://127.0.0.1:4100/api/content/post/" + uid + "/wintermead" /*, "http://127.0.0.1:4101/api/content/post/" + uid + "/wintermead"*/ ]
, ports = [ 4100 ];
var st = gt();
var postUrl = postTo[ Math.floor(Math.random()*postTo.length) ];
console.log( postUrl );
rest.post( postUrl,
{
"data": data
, "headers":
{ "kloudid": kloudId, 'Connection':'close', 'Connection-Timeout': 10 }
}
).on('complete',
function( data, response )
{
gt( "end: ",st );
if (response.statusCode == 202 ||response.statusCode == 201 || response.statusCode == 200)
{
try {
data =JSON.parse( data );
} catch(e) {}
if( data && data.error )
console.log( "1", data.message );
else
console.log( "2", data._id );
// you can get at the raw response like this...
}
else
{
console.log( "! Error ", response.statusCode, data );
}
}
);
}
function gt( name, lastTime )
{
if( !name || name=="start" )
{
var d = new Date().getTime();
var uu = uuid.new();
return (d + "|" + uu);
}
else if( lastTime )
{
var props = lastTime.split("|");
var time = parseInt(props[0]);
var uu = props[1];
console.log( uu, name, ( new Date().getTime() - time ));
}
else
{
console.log( "logging: invalid start time " + name);
}
}