我正在做一些负载测试和编写节点脚本来做到这一点。我的结果非常糟糕,直到我意识到我的测试代码应该受到责备才吓坏了我。我平均每秒约30-50个请求(进入服务器)使用下面的代码来发出请求。 30-50看起来非常低。这是在4核Mac上。这是对的还是我做错了什么?
var http = require('http');
var sys = require('util');
http.globalAgent.maxSockets = 100000;
var http = require('http');
http.globalAgent.maxSockets = 100000;
var Request = function (request, params, host, port, completionFn, errorFn)
{
if(!params)
params = '';
if(typeof(errorFn) != 'function')
{
errorFn = function (e)
{
console.log('request error!? ' + e.message);
process.exit();
}
}
var paramsStr = '';
for(var item in params)
paramsStr += '&' + item + '=' + encodeURI(params[item]);
var path = '/' + request;
if(paramsStr != '')
path += '?' + paramsStr.substr(1);
var options =
{
host: host,
port: port,
path: path,
agent: false
};
http.request(options,
function (response)
{
var responseData = '';
response.on('data',
function (chunk)
{
responseData += chunk;
}
).on('end',
function ()
{
completionFn(httpRequest.To_JSON(responseData));
}
).on('error', errorFn);
}
).on('error', errorFn).end();
};
新信息:
有趣的是,在Chrome中运行此功能可以让我每秒发送大约250个请求,这对于单个节点来说似乎更合理。虽然浏览器确实很快崩溃了。
for(var i = 0; i < 1000000; i++)
{
$.get('/service', {index:i},function(result){}).error(
function()
{
out.append('fail ');
}
);
}
答案 0 :(得分:0)
/*jshint node:true */
var http = require('http');
var i = 100;
var called = 0;
while (i--) {
requestGoogle();
}
function requestGoogle() {
'use strict';
var requestNum = called++;
console.log('CALLED: ' + called);
var options = {
hostname: 'www.google.com',
port: 80,
path: '/',
method: 'GET'
};
var req = http.request(options, function (res) {
res.setEncoding('utf8');
res.on('data', function () {
console.log('RECIEVING DATA ON: ' + requestNum);
});
res.on('end', function () {
console.log('CALLED: ' + --called);
});
});
req.on('error', function (e) {
console.log('problem with request: ' + e.message);
});
req.end();
}
所以,当我运行这个例子时,我注意到两件事。首先,在开始时,我正在为各种请求获得良好的数据组合:
接收数据:2 接收数据:0 接收数据:2 接收数据:0 接收数据:3 接收数据:3 接收数据:3 接收数据:3 接收数据:3 接收数据:3 接收数据:3 接收数据:1 接收数据:1 接收数据:1 接收数据:1 接收数据:1 接收数据:1 接收数据:1 接收数据:1 接收数据:4 接收数据:4 接收数据:4
我们正在看到来自请求1,4,3,0,2的所有块...同时进入...真棒!好吧,经过一段时间后,这种行为会提炼出最终成为非常线性的结果集,并且完全没有混合。最后,我们将事件循环与排队请求组合在一起。当我们执行这个逻辑服务器端时,不是这个立即循环函数调用,而是立即对请求进行排队。无论有多少请求进入服务器(DDOS条件除外),节点进程调用它的事件处理程序并返回主事件循环的周期很少。
当你做一个客户端,while循环,产生请求时,这些宝贵的几个周期都不可用。相反,我们有一个拥挤的事件循环,最终导致对您的请求进行基本上线性的处理,一旦初始的10-13请求接收到数据,他们就会按顺序开始接收它,并且事情发生的速度比您预期的要慢得多,与节点处理服务器端请求的速度相比,因为我们有一个过度拥挤的事件循环。您的客户端程序基本上是DOS自己! :)。
您可以尝试通过增加套接字数量来抑制此行为,但最终您的计算机将耗尽文件描述符。此时,节点将在所涉及的调用上崩溃/调用错误处理程序,或者减慢并等待文件描述符变为可用,从而以非常线性的同步方式处理将来的请求。有一些方法可以增加文件描述符,但最终要正确地进行基准测试,您需要多台计算机。没有设计操作系统来处理足够的套接字描述符/网络I / O,以便对单个节点服务器进行充分的压力测试。如果是这种情况,DDOS攻击会容易得多!
另外:看看JMeter,压力测试的客户端比节点好得多。