1

我正在尝试使用 cradle 作为 DB 驱动程序来测量一个简单的 Node.js 程序的吞吐量,该程序带有一个 CouchDB 后端。当我对程序加载时,我在 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,地址已在使用”错误?为什么等待套接字的数量如此之多?

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

Are you sure you don't have a zombie process on 8001?

    ps aux | grep node

might help

Also wrote an article to help people get started with node and couchdb, if you are interested you can check out http://writings.nunojob.com/2011/09/getting-started-with-nodejs-and-couchdb.html

于 2011-09-12T00:41:23.213 回答
2

升级到 Cradle 0.5.6。它没有问题。

关于问题的猜测

等待的套接字可能处于 CLOSE_WAIT 状态。(还有其他状态可以匹配您的grep,例如TIME_WAIT。您能确认它是CLOSE_WAIT,而不是其他任何状态吗?)

链接的帖子有一个有用的报价:

RF793 说 CLOSE_WAIT 是等待本地应用程序释放套接字的 TCP/IP 堆栈。因此,它挂起是因为它已收到远程主机已启动断开连接并正在关闭其套接字的信息,而本地应用程序并未关闭其自身。

所以也许解决方案在于为您的应用程序找到错误修复......

的确。在您的情况下,每个查询有两个连接,一个从 JMeter 到 Node,另一个从 Node 到 CouchDB。JMeter(较旧的较成熟的软件)未正确关闭连接,或者 Cradle(较新,较不成熟的软件)未正确关闭连接。显然,Cradle 是最有可能出现这个 bug 的。(也许它是 NodeJS 的 HTTP 库本身,但 Cradle 似乎是第一个检查的地方。)

我没有完整的答案,但希望这些将是有用的线索。我认为使用中的地址错误是因为没有更多的地址可以建立“传出”(即使对于 127.0.0.1)连接。但到目前为止,我不确定为什么每次试验中的 CLOSE_WAIT 计数都不同。(也许随着整个连接池的关闭,它会大幅波动。)

要获得更多信息,也许可以尝试使用其他 CouchDB 客户端库(例如requestnano )并比较结果。

请我们知道您发现了什么,因为识别并关闭这个潜在的 Cradle 错误(或至少某个地方的错误!)会很棒。谢谢。

于 2011-09-12T00:19:21.710 回答