【发布时间】:2011-06-01 23:55:34
【问题描述】:
这是我的示例代码:
var http = require('http');
var options1 = {
host: 'www.google.com',
port: 80,
path: '/',
method: 'GET'
};
http.createServer(function (req, res) {
var start = new Date();
var myCounter = req.query['myCounter'] || 0;
var isSent = false;
http.request(options1, function(response) {
response.setEncoding('utf8');
response.on('data', function (chunk) {
var end = new Date();
console.log(myCounter + ' BODY: ' + chunk + " time: " + (end-start) + " Request start time: " + start.getTime());
if (! isSent) {
isSent = true;
res.writeHead(200, {'Content-Type': 'application/xml'});
res.end(chunk);
}
});
}).end();
}).listen(3013);
console.log('Server running at port 3013');
我发现,如果我连接到其他服务器(谷歌或任何其他服务器),响应会越来越慢到几秒钟。如果我连接到同一网络中的另一个 node.js 服务器,则不会发生这种情况。
我使用 JMeter 进行测试。每秒 50 个并发,1000 个循环。
我不知道问题是什么......
===========================
进一步调查:
我在 Rackspace 和 EC2 上运行相同的脚本进行测试。该脚本将使用 http.request 连接到:Google、Facebook 以及我的另一个脚本,该脚本仅输出由另一个 EC2 实例托管的数据(如 hello world)。
我刚才的测试工具是我桌面上的jMeter。
pre-node.js 测试: jMeter -> Google 结果:快速且一致。 jMeter -> Facebook 结果:快速且一致。 jMeter -> 我的简单输出脚本结果:快速且一致。
然后我创建一个 50 Concurrent Threads /sec ,有 100 个循环,测试我的 Rackspace nodejs,然后是 EC2 node.js,它具有相同的性能问题之王
jMeter -> node.js -> Google 结果:在 200 个请求中从 50 毫秒变为 2000 毫秒。
jMeter -> node.js -> Facebook 结果:200 次请求后从 200 毫秒变为 3000 毫秒。
jMeter -> node.js -> 我的简单输出脚本结果:在 200 次请求后从 100 毫秒变为 1000 毫秒。
前 10-20 个请求很快,然后开始变慢。
然后,当我更改为 10 个并发线程时,情况开始发生变化.. 响应非常一致,没有变慢。
与 Node.js (http.request) 可以处理的并发线程数有关。
------------ 更多 --------------
我今天做了更多测试,结果如下: 我使用了 http.Agent 并增加了最大套接字。然而,有趣的是,在一个测试服务器 (EC2) 上,它改进了很多并且不再减慢。然而,其他服务器(机架空间)只改进了一点。它仍然显示缓慢。我什至在请求标头中设置了“连接:关闭”,它只提高了 100 毫秒。
如果http.request使用了连接池,如何增加?
在两个服务器中,如果我执行“ulimit -a”,打开的文件数为 1024。
------------- ** 越来越多 ** --------
似乎即使我将 maxSockets 设置为更高的数字,它也只能在某些限制下工作。似乎存在内部或操作系统相关的套接字限制。然而要顶一下?
------------- ** 经过大量测试 ** ---------------
看了很多帖子,我发现:
引用自:https://github.com/joyent/node/issues/877
1) 如果我用 connection = 'keep-alive' 设置标头,性能很好并且可以达到 maxSocket = 1024(这是我的 linux 设置)。
var options1 = {
host: 'www.google.com',
port: 80,
path: '/',
method: 'GET',
**headers: {
'Connection':'keep-alive'
}**
};
如果我将它设置为“连接”:“关闭”,响应时间会慢 100 倍。
这里发生了有趣的事情:
1) 在 EC2 中,当我第一次使用 Connection:keep-alive 进行测试时,大约需要 20-30 毫秒。然后,如果我更改为 Connection:Close 或设置 Agent:false,响应时间将减慢到 300 毫秒。如果不重新启动服务器,如果我再次更改为 Connection:keep-alive,响应时间将进一步减慢至 4000 毫秒。要么我必须重新启动服务器,要么等待一段时间才能恢复我 20-30 毫秒的光速响应。
2) 如果我使用 agent:false 运行它,一开始响应时间会减慢到 300 毫秒。但随后,它会再次变得更快并恢复“正常”。
我的猜测是即使您设置了 agent:false,连接池仍然有效。但是,如果您保持连接:保持活动状态,那么它肯定会很快。只是不要切换它。
2011 年 7 月 25 日更新
我尝试了最新的 node.js V0.4.9 以及来自https://github.com/mikeal/node/tree/http2 的 http.js 和 https.js 修复
性能更好更稳定。
【问题讨论】:
-
你应该监听
response.on('end')事件,而不是这样做isSent魔术。 -
我遇到了同样的问题,并且通过保持活动更改看到了相当大的性能提升,但是在负载测试一段时间后我遇到了错误。以下是错误:{ [Error: connect EADDRNOTAVAIL] code: 'EADDRNOTAVAIL', errno: 'EADDRNOTAVAIL', syscall: 'connect' }
-
此评论中的链接现在给出 404 错误。
标签: http node.js request load-testing