1

クレードルを DB ドライバーとして使用して、CouchDB バックエンドで単純な Node.js プログラムのスループットを測定しようとしています。プログラムに負荷をかけると、30 秒以内に次のエラーが表示されます。

EADDRINUSE、アドレスは既に使用されています

これが私のプログラムです:

var http = require ('http'),
    url = require('url'),
    cradle = require('cradle'),
    c = new(cradle.Connection)('127.0.0.1',5984,{cache: false, raw: false}),
    db = c.database('testdb'),
    port=8081;

http.createServer(function(req,res) {
    var id = url.parse(req.url).pathname.substring(1);  
    db.get(id,function(err, doc) {
      res.writeHead(200,{'Content-Type': 'application/json'});
      res.write(JSON.stringify(doc));
      res.end();
    });
}).listen(port);

console.log("Server listening on port "+port);

50 人の同時ユーザーで JMeter スクリプトを使用しています。平均応答時間は 120 ミリ秒で、返されたドキュメントの平均サイズは 3 KB です。

ご覧のとおり、Cradle のキャッシュを false に設定しました。調査するために、待機中のソケットの数を調べました。約 4000 まで増加し、その時点でクラッシュします (netstat | grep WAIT | wc -l)。

他のオプションをテストするために、キャッシュを true に設定しました。この場合、プログラムはクラッシュしませんが、待機中のソケットの数は時間の経過とともにほぼ 10000 に増加します。

また、Java サーブレットとして同じプログラム (非同期部分を除く) を作成しましたが、待機中のソケットの数が 20 をはるかに超えることなく正常に実行されました。

私の質問は、「EADDRINUSE、アドレスは既に使用されています」というエラーが表示されるのはなぜですか? 待機中のソケットの数が非常に多いのはなぜですか?

PS: これは、netstat|grep WAIT の出力の抜粋です。

tcp4       0      0  localhost.5984         localhost.58926        TIME_WAIT
tcp4       0      0  localhost.5984         localhost.58925        TIME_WAIT
tcp4       0      0  localhost.58924        localhost.5984         TIME_WAIT
tcp4       0      0  localhost.58922        localhost.5984         TIME_WAIT
tcp4       0      0  localhost.5984         localhost.58923        TIME_WAIT
4

2 に答える 2

2

8001 にゾンビ プロセスがありませんか?

    ps aux | grep node

役立つかもしれません

nodeとcouchdbを使い始めるのに役立つ記事も書きました。興味がある場合は、http://writings.nunojob.com/2011/09/getting-started-with-nodejs-and-couchdb.htmlをチェックしてください。

于 2011-09-12T00:41:23.213 に答える
2

クレードル 0.5.6 にアップグレードします。問題ありません。

問題についての憶測

待機中のソケットはおそらく CLOSE_WAIT 状態です。grep(など、あなたの に一致する州は他にもありますTIME_WAIT。他の州ではなく、それであることを確認できますCLOSE_WAITか?)

リンクされた投稿には、役立つ引用があります。

RF793 によると、CLOSE_WAIT は、ローカル アプリケーションがソケットを解放するのを待っている TCP/IP スタックです。そのため、リモート ホストが切断を開始し、ソケットを閉じようとしているという情報を受信したため、ローカル アプリケーションが自身の側を閉じなかったためにハングします。

したがって、おそらく解決策は、アプリケーションのバグ修正を見つけることです...

それはそう。あなたの場合、クエリごとに2 つの接続があり、1 つは JMeter から Node へ、もう 1 つは Node から CouchDB へです。JMeter (より成熟した古いソフトウェア) が接続を適切に閉じていないか、Cradle (より新しく成熟していないソフトウェア) が接続を適切に閉じていません。明らかに、Cradle にバグがある可能性が最も高いです。(おそらく NodeJS の HTTP ライブラリ自体ですが、Cradle が最初にチェックする場所のようです。)

完全な答えはありませんが、これらが役立つ手がかりになることを願っています。使用中のアドレス エラーは、「送信」(127.0.0.1 の場合でも) 接続を行うための送信アドレスがなくなったためだと思います。しかし、試行ごとに CLOSE_WAIT カウントが異なる理由は今のところわかりません。(おそらく、接続プール全体が閉じられているため、大きく変動しています。)

より多くの情報を得るには、 requestnanoなどの別の CouchDB クライアント ライブラリを試して、結果を比較してください。

この潜在的な Cradle バグ (または少なくともどこかのバグ!) を特定してクローズすることができれば幸いです。ありがとう。

于 2011-09-12T00:19:21.710 に答える