使用 cradle 和 CouchDB 对 Node.js 进行压力测试时,会出现以下错误:EADDRINUSE、地址已在使用中,这是怎么回事?

发布于 2024-12-04 05:11:38 字数 1525 浏览 1 评论 0原文

我正在尝试使用 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,地址已在使用中”错误?为什么等待套接字的数量如此之多?

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

I am trying to measure the throughput of a simple Node.js program with a CouchDB backend using cradle as the DB driver. When I put load against the program I get the following error within 30 seconds:

EADDRINUSE, Address already in use

Here is my program:

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);

I am using a JMeter script with 50 concurrent users. The average response time is 120ms, average size of the document returned 3KB.

As you can see I set the caching of Cradle to false. To investigate I looked at the number of waiting sockets: It increases up to about 4000, at which point it crashes (netstat | grep WAIT | wc -l)

To test other options I set the caching to true. In this case the program doesn't crash, but the number of waiting sockets increases to almost 10000 over time.

I also wrote the same program (sans the asynchronous part) as a Java Servlet, and it runs fine without the number of waiting sockets increasing much beyond 20.

My question is: Why do I get the ' EADDRINUSE, Address already in use' error? Why is the number of waiting sockets so high?

P.S.: This is a snippet from the output of 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

意犹 2024-12-11 05:11:39

你确定8001上没有僵尸进程吗?

    ps aux | grep node

可能会有所帮助

还写了一篇文章来帮助人们开始使用node和couchdb,如果您有兴趣可以查看http://writings.nunojob.com/2011/09/getting-started-with-nodejs-and-couchdb.html

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

偏爱你一生 2024-12-11 05:11:39

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

关于问题的推测

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

)链接的帖子有一个有用的引用:

RF793 表示 CLOSE_WAIT 是 TCP/IP 堆栈正在等待本地应用程序
释放套接字。所以,它挂起是因为它已收到信息
远程主机已发起断开连接并正在关闭其
套接字,本地应用程序没有关闭自己的一侧。

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

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

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

要获取更多信息,也许可以尝试替代 CouchDB 客户端库,例如 requestnano 并比较结果。

请告诉我们您发现了什么,因为如果能够识别并关闭这个潜在的 Cradle 错误(或者至少在某个地方的错误!),那就太棒了。谢谢。

Upgrade to Cradle 0.5.6. It does not have the problem.

Speculation about the problem

The waiting sockets are probably in the CLOSE_WAIT state. (There are other states that would match your grep, such as TIME_WAIT. Can you confirm that it is CLOSE_WAIT and not anything else?)

The linked post has a helpful quote:

RF793 says CLOSE_WAIT is the TCP/IP stack waiting for the local application
to release the socket. So, it hangs because it has received the information
that the remote host has initiated a disconnection and is closing its
socket, upon what the local application did not close its own side.

So maybe the solution consists in finding a bug fix for your application...

Indeed. In your case, there are two connections per query, one from JMeter to Node, and another from Node to CouchDB. Either JMeter (older more mature software) is not closing the connection properly, or Cradle (newer, less mature software) is not closing the connection properly. Obviously, Cradle is the most likely to have the bug. (Perhaps it is NodeJS's HTTP library itself, but Cradle seems like the first place to check.)

I do not have a complete answer, but hopefully these will be helpful clues. I think the address-in-use error is because there are no more source addresses to make an "outgoing" (even for 127.0.0.1) connection. But I am so far unsure why the CLOSE_WAIT count is different in each trial. (Perhaps it is fluctuating heavily as entire connection pools are closed.)

To gain more information, perhaps try an alternative CouchDB client library such as request or nano and compare the results.

Please us know what you find because it would be great to identify and close this potential Cradle bug (or bug somewhere at least!). Thanks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文