下面是我要做的事情:我正在开发一台Node.js http服务器,它将在一台机器上从数万个移动客户端进行长时间连接(与redis协作)。
测试环境:
1.80GHz*2 CPU/2GB RAM/Unbuntu12.04/Node.js 0.8.16在第一次使用“快速”模块时,我可以在交换前达到大约120 K的并发连接,这意味着RAM不够。然后,我切换到本地的"http“模块,并发性达到了160 K。但是我意识到在本机http模块中仍然有太多的功能不需要,所以我将它切换到本机"net“模块(这意味着我需要自己处理http协议,但没关系)。现在,我可以达到大约250 K的并发连接每台机器。
以下是我的代码的主要结构:
var net = require('net');
var redis = require('redis');
var pendingClients = {};
var redisClient = redis.createClient(26379, 'localhost');
redisClient.on('message', function (channel, message) {
var client = pendingClients[channel];
if (client) {
client.res.write(message);
}
});
var server = net.createServer(function (socket) {
var buffer = '';
socket.setEncoding('utf-8');
socket.on('data', onData);
function onData(chunk) {
buffer += chunk;
// Parse request data.
// ...
if ('I have got all I need') {
socket.removeListener('data', onData);
var req = {
clientId: 'whatever'
};
var res = new ServerResponse(socket);
server.emit('request', req, res);
}
}
});
server.on('request', function (req, res) {
if (res.socket.destroyed) {
return;
}
pendingClinets[req.clientId] = {
res: res
};
redisClient.subscribe(req.clientId);
res.socket.on('error', function (err) {
console.log(err);
});
res.socket.on('close', function () {
delete pendingClients[req.clientId];
redisClient.unsubscribe(req.clientId);
});
});
server.listen(3000);
function ServerResponse(socket) {
this.socket = socket;
}
ServerResponse.prototype.write = function(data) {
this.socket.write(data);
}最后,以下是我的问题:

有人能解释一下吗?(数组)/(编译代码)/(字符串)/命令/数组的数量和大小增加了很多,这意味着什么?
编辑:我是如何运行加载测试的?
ulimit -Hn 999999
ulimit -Sn 9999991.2。在服务器机器上,我还修改了一些与net/tcp相关的内核参数,其中最重要的是:
net.ipv4.tcp_mem = 786432 1048576 26777216
net.ipv4.tcp_rmem = 4096 16384 33554432
net.ipv4.tcp_wmem = 4096 16384 335544321.3。至于客户端机器:
net.ipv4.ip_local_port_range = 1024 65535编辑:我确实在一台机器上达到了250 k并发连接(2GBRAM),但事实证明,它并不是很有意义和实用性。因为当连接连接时,我只让连接挂起,没有别的。当我试图向他们发送回复时,并发数下降到150 K左右。据我计算,每个连接有大约4KB的内存使用量,我想它与net.ipv4.tcp_wmem有关,我将其设置为4096 16384 33554432,但即使我将其修改为更小,也没有什么变化。我搞不懂为什么。
编辑:实际上,现在我更感兴趣的是每个tcp连接使用了多少内存,以及单个连接所使用的内存的确切组成是什么?根据我的测试数据:
150 k并发性消耗了大约1800百万内存(来自free -m输出),Node.js进程有大约6亿RSS。
然后,我假设:
我说的对吗?如何减少这两个方面的内存使用量?
如果有什么地方我没有很好的描述,让我知道,我会完善它!如有任何解释或建议,将不胜感激!
发布于 2012-12-29 18:42:20
不过,更重要的是,我想知道您是如何加载测试的。我曾经尝试过像这样进行大规模的负载测试,而大多数工具根本无法在linux上生成这样的负载,因为开放文件描述符的数量有限(默认情况下每个进程大约有1000个)。同样,一旦使用了套接字,就不能立即再次使用它。据我回忆,这需要一分钟的时间才能再次使用。在此与我通常看到系统打开的文件描述符限制设置在100 K以下这一事实之间,我不确定在未经修改的盒子上是否能够接收到这么多负载,或者在单个框上生成它。由于您没有提到任何这样的步骤,我认为您可能还需要研究负载测试,以确保它正在执行您的想法。
发布于 2013-01-03 20:57:51
只是几个音符:
您需要在对象{ res : res}中包装res吗?您可以直接分配它吗?
pendingClinets[req.clientId] = res;编辑另一种可能有助于进行微优化的方法
server.emit('request', req, res);将两个参数传递给“request”,但是您的请求处理程序实际上只需要响应“res”。
res['clientId'] = 'whatever';
server.emit('request', res);虽然实际数据量保持不变,但在“请求”处理程序参数列表中使用少一个参数将为您节省一个引用指针(几个字节)。但是,当您处理几十万个连接时,几个字节就会加起来。您还将节省处理发出调用上的额外参数的次要cpu开销。
https://stackoverflow.com/questions/14049109
复制相似问题