我正在尝试使用cradle作为数据库驱动程序来测量使用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脚本。平均响应时间为120ms,文档平均大小为3KB。
正如您所看到的,我将Cradle的缓存设置为false。为了调查我查看了等待套接字的数量:它增加到大约4000,此时它崩溃了(netstat | grep WAIT | wc -l)
要测试其他选项,我将缓存设置为true。在这种情况下,程序不会崩溃,但等待套接字的数量会随着时间的推移而增加到近10000个。
我还编写了相同的程序(没有异步部分)作为Java Servlet,它运行良好,没有等待套接字的数量增加超过20。
我的问题是:为什么我收到'EADDRINUSE,地址已在使用中'错误?为什么等待插座的数量如此之高?
P.S。:这是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
答案 0 :(得分:2)
升级到Cradle 0.5.6。它没有问题。
等待套接字为probably in the CLOSE_WAIT state。 (还有其他状态与grep
匹配,例如TIME_WAIT
。您能确认它是CLOSE_WAIT
而不是其他任何状态吗?)
链接的帖子有一个有用的引用:
RF793表示CLOSE_WAIT是等待本地应用程序的TCP / IP堆栈 释放套接字。因此,它因为收到了信息而挂起 远程主机已启动断开连接并正在关闭它 socket,根据本地应用程序没有关闭自己的一面。
因此,解决方案可能包括为您的应用程序找到错误修复程序......
事实上。在您的情况下,每个查询有两个连接,一个从JMeter到Node,另一个从Node到CouchDB。 JMeter(较旧的更成熟的软件)没有正确关闭连接,或者Cradle(较新的,不太成熟的软件)没有正确关闭连接。显然,Cradle最容易出错。 (也许它是NodeJS的HTTP库本身,但Cradle似乎是第一个检查的地方。)
我没有完整的答案,但希望这些将是有用的线索。我认为使用中的地址错误是因为没有更多的源地址来建立“传出”(即使是127.0.0.1)连接。但我到目前为止还不确定为什么CLOSE_WAIT计数在每次试验中都不同。 (当整个连接池关闭时,它可能会波动很大。)
要获取更多信息,可以尝试替代CouchDB客户端库,例如request或nano,并比较结果。
请告诉我们你发现了什么,因为识别和关闭这个潜在的Cradle bug(或至少错误某处)会很棒!感谢。
答案 1 :(得分:2)
你确定8001上没有僵尸程序吗?
ps aux | grep node
可能有帮助
还写了一篇文章来帮助人们开始使用node和couchdb,如果您有兴趣可以查看http://writings.nunojob.com/2011/09/getting-started-with-nodejs-and-couchdb.html