3

我想测试我的redis服务器可以容纳多少连接,所以我在循环中调用redis.createClient(),当redis服务器仍然运行时,我得到了EMFILE错误,我知道我的fds已经用完了。

但是等等,我之前刚刚测试了我的 mqtt 服务器,我对我的 mqtt 服务器做了同样的事情,我在 20000 的 10000 的循环中调用了 mqtt.createClient() ......但我从来没有收到 EMFILE 错误。

那么,nodejs mqtt 库是否在下面使用了不同的机制?

redis-client.js:

var redis = require('redis');

function start() {
    var client = redis.createClient();

    client.on('error', function(err) {
        console.log('Error ' + err);
    });
}

exports.start = start;

redis-test.js

var redis_client = require('./redis-client');

for(var i = 0 ; i < 10000 ; ++i) {
    redis_client.start();
    console.log('redis client ' + i + ' started');
}

mqtt-subclient.js

var mqtt = require('mqtt');
function start() {
    var client = mqtt.createClient();
    client.subscribe('message');

    //client.publish('message', 'hello me!');
    client.on('message', function(topic, message) {
        console.log('receive message: ');
        console.log(message);
    });

    client.on('connack', function(packet) {
        console.log(packet);
        if(packet.returnCode == 0) {
            console.log('connect successfully');
        }
    });

    client.on('suback', function(packet) {
        console.log(packet.messageId);
    });

    client.on('error', function(err) {
        console.log(err);
    });
}

exports.start = start;

mqtt-test.js

var subclient = require('./mqtt-subclient.js');

for(var i = 0 ; i < 10000 ; ++i) {
    subclient.start();
    console.log('client ' + i + ' started');
}
4

1 回答 1

1

Redis 不能接受超过 x 次的同时连接尝试,其中 x 是 listen 系统调用的 backlog 参数。

它受到 somaxconn 内核参数(128 是常见的默认值)和 512 之间的最小值的限制。因此,如果您尝试超过 min(somaxconn,512) 个同时连接,则可能会出错。如果您在连接尝试之间添加一小段延迟,它应该可以解决此问题。

然后,您需要检查您是否有足够的资源来打开 10000 个文件描述符(检查 ulimit -a 的输出),并且您的 TCP/IP 临时端口范围是否足够大以容纳如此多的客户端连接。

于 2013-07-23T12:41:22.180 回答