Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js Http.request在负载测试下会变慢。我做错什么了吗?_Http_Node.js_Request_Load Testing - Fatal编程技术网

Node.js Http.request在负载测试下会变慢。我做错什么了吗?

Node.js Http.request在负载测试下会变慢。我做错什么了吗?,http,node.js,request,load-testing,Http,Node.js,Request,Load Testing,以下是我的示例代码: var http = require('http'); var options1 = { host: 'www.google.com', port: 80, path: '/', method: 'GET' }; http.createServer(function (req, res) { var start = new Date(); v

以下是我的示例代码:

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个并发线程(100个循环)的速度测试我的Rackspace NodeJ,然后是EC2 node.js,它也有同样的性能问题 jMeter->node.js->Google结果:在200个请求中从50毫秒到2000毫秒。
jMeter->node.js->Facebook结果:200次请求后,从200毫秒到3000毫秒。
jMeter->node.js->我的简单输出脚本结果:从100毫秒到200次请求后的1000毫秒。
前10-20个请求很快,然后开始变慢

然后,当我更改为10个并发线程时,情况开始发生变化。。反应非常一致,没有减速

与Node.js(http.request)可以处理的并发线程数有关

------------更多--------------

我今天做了更多的测试,结果如下: 我使用了http.Agent并增加了最大套接字。然而,有趣的是,在一台测试服务器(EC2)上,它改进了很多,并且不再减慢速度。但是,另一台服务器(rackspace)只提高了一点。它仍然显示慢下来。我甚至在请求头中设置了“Connection:close”,它只提高了100ms

如果http.request正在使用连接池,如何增加它

在这两个服务器中,如果执行“ulimit-a”,则文件打开的#数为1024

-------------***越来越多**-------------------

似乎即使我将maxSockets设置为更高的数字,它也只能在某些限制下工作。似乎存在内部或依赖于操作系统的套接字限制。怎么把它撞上去

-------------**经过广泛测试**---------------

在阅读了大量帖子后,我发现:



引自:


1) 如果我使用connection='keep alive'设置头,那么性能很好,可以达到maxSocket=1024(这是我的linux设置)

如果我将其设置为“连接”:“关闭”,响应时间将慢100倍

这里发生了有趣的事情:

1) 在EC2中,当我第一次使用Connection:keep alive进行测试时,大约需要20-30毫秒。然后,如果我更改为Connection:Close或set-Agent:false,响应时间将降低到300毫秒。在不重新启动服务器的情况下,如果我再次更改为Connection:keep alive,响应时间将进一步降低到4000毫秒。我要么重新启动服务器,要么等待一段时间,以恢复20-30毫秒的光速响应

2) 如果我使用agent:false运行它,首先,响应时间将减慢到300ms。但之后,它将再次变得更快,并恢复到“正常”

我猜即使您将代理设置为false,连接池仍然有效。然而,如果您保持连接:保持活动,那么肯定会很快。别换了




更新日期:2011年7月25日

我尝试了最新的node.js V0.4.9,其中包含http.js和https.js修复程序


性能更好、更稳定。

这并不一定能解决您的问题,但它会稍微清理一下您的代码,并以您应该采用的方式利用各种事件:

var http=require('http');
变量选项1={
主持人:“www.google.com”,
港口:80,
路径:“/”,
方法:“获取”
};
http.createServer(函数(req,res){
var start=新日期();
var myCounter=req.query['myCounter']| | 0;
请求(选项1,函数(响应){
res.on('drain',函数(){//当输出流的缓冲区耗尽时
response.resume();//继续从输入流接收
});
response.setEncoding('utf8');
res.writeHead(response.statusCode,{'Content-Type':'application/xml'});
响应.on('data',函数(块){
如果(!res.write(chunk)){//如果写入失败,则流阻塞
response.pause();//告诉传入流等待输出流耗尽
}
}).on('end',函数(){
var end=新日期();
log(myCounter+'time:'+(end-start)+“请求开始时间:”+start.getTime());
res.end();
});
}).end();
}).听(3013);
log('Server running at port 3013');
我移除了身体的输出。由于我们正在从一个套接字流到另一个套接字,我们无法确保在没有缓冲的情况下随时看到整个身体

编辑:我相信节点正在对http.request使用连接池。如果您有50个并发连接(因此有50个并发http.request尝试),则可能会遇到连接池限制。我目前没有时间为您查找,但是您应该看看关于http的节点文档,特别是http代理

编辑2:node.js邮件列表上有一个非常类似的问题。你应该看看,特别是米凯尔的帖子应该很有意思。他建议完全关闭req的连接池
var options1 = {
                  host: 'www.google.com',
                  port: 80,
                  path: '/',
                  method: 'GET',
    **headers: {
            'Connection':'keep-alive'
    }**
                };
require('http').globalAgent.maxSockets = 100000
agent = new http.Agent()
agent.maxSockets = 1000000  # 1 million
http.request({agent:agent})