【问题标题】:Error: Redis connection to 127.0.0.1:6379 failed - connect EMFILE错误:与 127.0.0.1:6379 的 Redis 连接失败 - 连接 EMFILE
【发布时间】:2014-11-07 16:51:08
【问题描述】:

所以我创建了一个使用 socket.io、redis 和 node.js 的实时应用程序。

问题是,有 30 个用户,我已经达到服务器的连接数(我正在运行 Ubuntu 14.04。

而且我认为这与我连接到 redis 的方式有关。

所以在一页上,我最多可以订阅 12 个频道。在两个 socket.io 连接上,一个有 6 个通道,另一个有其他 6 个通道。

在展示我的节点 js 代码之前,我所做的是为每个频道创建一个新的 redis 客户端,所以假设我有一个 insertupdate频道,在 node.js 代码上,所以我的代码将是:

var data = io.of('/data');
data.on('connection', function(client) {
    var insert = redis.createClient();
    var update = redis.createClient();

    insert.subscribe('insert');

    insert.on("message", function(channel, message) {
        client.emit('data_insert', message);
    });

    update.subscribe('update');
    update.on("message", function(channel, message) {
        client.emit('data_update', message);
    });
});

我相信这就是问题所在,这就是为什么我有 30 个用户超过了服务器的连接限制,因为 30 * 12 + 2 * 30 = 420,加上其他一些其他的,以及很容易达到 1024。

那么我该如何优化代码,将每个客户端的连接数减少到最多一到两个?

data.on('connection') 之外有 var insert = redis.createClient(); 有帮助吗??

【问题讨论】:

    标签: node.js redis


    【解决方案1】:

    您不应该为每个客户端创建一个(或多个)redis 连接 - 只需继续使用相同的全局连接即可。此外,实际上没有理由为您要订阅的每个频道创建一个客户端。只需使用 channel 参数来确定要对数据做什么(在这种情况下,您在每个通道上都在做同样的事情,因此单独的通道更没有意义)。

    var data = io.of('/data');
    var redis = redis.createClient();
    redis.subscribe('insert');
    redis.subscribe('update');
    data.on('connection', function(client) {
        redis.on("message", function(channel, message) {
            if(channel == 'insert')
                client.emit('data_insert', message);
            else if(channel == 'update')
                client.emit('data_update', message);
        });
    });
    

    可能有更好的方法可以做到这一点,但这是将您的代码相当直接地转换为仅使用一个 redis 连接的东西。

    请注意,redis 订阅者只能订阅 - 您需要第二个客户端来发布或执行任何其他 redis 操作。

    【讨论】:

    • 对不起,实际上我是在尝试做单独的事情,这是一个错误,你能给我一个代码示例,因为每次我尝试使用相同的redis客户端时,我只得到第一个订阅,而不是第二个..
    • @Tio 已编辑。这有帮助吗?
    • 是的,实际上我昨天设法解决了它,做了类似的事情,对我来说唯一的变化是我需要在 data.on('connection') 中订阅,因为有一个变量正在通过,该选择是正确的频道,谢谢..
    【解决方案2】:

    仅供参考(我今晚输了)

    这不起作用(它默认连接到 localhost:6379 无论你在 url 中输入什么):

    const redisURL = "redis://foo.bar.org:6379"
    redis.createClient( redisURL )
    

    但这确实有效(它也尝试连接 foo.bar.org)

    redis.createClient( {url: redisURL} )
    

    【讨论】:

      【解决方案3】:

      使用 socket.io 的namespace。在每个命名空间中,您还可以定义房间,但命名空间应该足以满足您的需求。

      【讨论】:

      • 实际上,我已经在使用 socket.io 的命名空间了,你可以在我发布的示例中看到......
      猜你喜欢
      • 2017-07-06
      • 2017-05-16
      • 2017-07-21
      • 2020-08-27
      • 2019-01-03
      • 2023-03-18
      • 1970-01-01
      • 2020-07-20
      • 2021-06-25
      相关资源
      最近更新 更多