最近学习node,看了很多教程,都在赞扬nodejs的异步I/O,异步I/O的特点就是,每接收一个请求,使用异步调用处理请求,不用等待结果,可以继续运行其他操作,也就是说可以继续接受请求。那它到底能接受?于是,我写了个程序来测试,代码如下:
// server.js
// 处理一个请求需要5秒,通过setTimeout设置5秒后响应
var http = require("http");
var n = 0;
http.createServer(function (req, res) {
n++;
setTimeout(function() {
console.log("Accept " + n + "request.");
res.end("test");
}, 5000);
}).listen(3000);
// client.js
// 发送一个请求
exports.send = function () {
var http = require('http');
var options = {
host: 'localhost',
port: '3000',
path: '/',
method: 'GET',
};
var req = http.request(options, function(res){
exports.counter += 1;
res.setEncoding('utf8');
res.on('data', function (c) {
//console.log(c);
});
res.on('end', function() {
exports.seccess += 1;
console.log("Response: " + exports.seccess);
});
});
req.end();
};
exports.seccess = 0;
// attack.js
// 在1秒内发出约50000个请求
var client = require('./client');
var d = 1000,
t = Date.now();
while(Date.now() - t < d) {
client.send();
}
console.log('end.');
运行server.js
> node server.js
运行atack.js发起请求,(经测试每秒能发出约50000个请求):
> node atack.js
结果:
Accept 5request.
Accept 5request.
Accept 5request.
Accept 5request.
Accept 5request.
Accept 10request.
Accept 10request.
Accept 10request.
Accept 10request.
Accept 10request.
Accept 15request.
Accept 15request.
Accept 15request.
Accept 15request.
Accept 15request.
// 省略后面N条
通过结果可以知道server.js在5秒内只接受了5个请求,这是为什么呢?
或者大家有什么办法可以测试这个问题呢?
哈哈哈哈哈。Node.js 的 socket 模块的一个限制导致的,好像是同一 IP 不能连接超过 5 个 socket。
我找找资料看。
http://nodejs.org/api/http.html#http_agent_maxsockets
对于同一个来源,比如 127.0.0.1:23423,Node.js 默认只接受最多 5 个请求。
去提高这个限制就好了。
一般设置多少合适呢? 每秒5个会不会太少? 如果遇到很多资源文件 图片的话…
@firhome 资源文件和图片放 CDN 啊。
对于楼主的实验来说,试试 require('http').globalAgent.maxSockets = Infinity
@alsotang 太感谢了,亲测可以更改maxSockets的值,但是这个值不能无限大,我测试了下最多只有4000左右,5000会导致客户端报错。
最后我把server.js的setTimeout的时间改成了100ms, maxSocket为2000大概返回 accept 1000个request 左右,也就是说100ms内接收了1000个request。
结论:所以如果不考虑其他因素,单谈接收的request的速率有10000/s。当然这个结果是很片面的,客户端和服务端在同一台电脑,两者的socket I/O的读写会相互影响结果(如我在调节maxSockets的值时,这个值越大,结果server的处理速度会越小)。
server的处理速度会越小??
还是 server的平均处理速度会越小?
@alsotang 准确来讲是平均接受并处理request"的速度会变小,可能是socket开多了会消耗CPU和内存?
@huanghuiquan 对嘛。我就知道是平均时间。因为处理单个 request 的请求应该是基本一样的,但是 maxSockets 开大了以后,每秒的处理数量变多了,所以平均速度会更快。
socket 开多了以后,可能CPU和内存不是瓶颈,而是 libuv 的事件循环成了瓶颈吧。(我瞎说的)
@alsotang 一个网页请求同一个cdn的图片的数量