错误:Redis连接到localhost:6379失败 - getaddrinfo EMFILE localhost:6379

时间:2017-03-01 18:21:18

标签: node.js redis

我收到以下错误。

Error: Redis connection to localhost:6379 failed - getaddrinfo EMFILE localhost:6379
at Object.exports._errnoException (util.js:870:11)
at errnoException (dns.js:32:15)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:78:26)

使用具有MySQL db和redis概念的Node.js。 从MySQL获取数据的请求太多,因此通过与db同步将数据缓存2分钟。因此,当新请求到达时,如果发现其服务来自redis,则检查redis否则从MySQL检索数据并以redis缓存并作为响应发送。这种情况一直在发生。

经过一段时间大概1小时或2小时后,服务器崩溃导致上述错误。 但截至目前,使用pm2重启服务器。

但需要知道它的原因。

Redis安装遵循此处的说明。 https://www.digitalocean.com/community/tutorials/how-to-install-and-use-redis

Snapshot

请让我知道如何解决问题...

Redis连接文件代码

var Promise = require('bluebird');
var redisClient;        // Global (Avoids Duplicate Connections)

module.exports = 
{
    OpenRedisConnection : function()
    {
        if (redisClient == null) 
        {
            redisClient = require("redis").createClient(6379, 'localhost');
            redisClient.selected_db = 1;
        }
    },
    GetRedisMultiConnection: function () 
    {
        return require("redis").createClient(6379, 'localhost').multi();       
    },
    IsRedisConnectionOpened : function()
    {
        if (redisClient && redisClient.connected == true) 
        {
            return true;
        }
        else 
        {
            if(!redisClient)
                redisClient.end();  // End and open once more

            module.exports.OpenRedisConnection();

            return true;
        }
    }
};

1 个答案:

答案 0 :(得分:0)

我通常使用这样的代码编写一个非常精简的模块,该模块加载到正确的Redis驱动程序中并返回一个有效的句柄,而且操作极少:

var Redis = require("redis");

module.exports = {
  open: function() {
    var client = Redis.createClient(6379, 'localhost');
    client.selected_db = 1;

    return client;
  },
  close: function(client) {
    client.quit();
  }
};

Node应用程序中需要Redis句柄的任何代码都会按需获取,并且无论发生什么情况,代码都必须关闭它。如果您没有发现错误,或者如果您发现错误并跳过了关闭,那么您就会发现错误"打开Redis手柄,你的应用程序最终会崩溃。

所以,例如:

 var Redis = require('./redis'); // Path to module defined above

 function doStuff() {
   var redis = Redis.open();

   thing.action().then(function() {
     redis.ping();
   }).finally(function() {
     // This code runs no matter what even if there's an exception or error
     Redis.close(redis);
   });
 }

由于具有单个Redis句柄的Node代码的并发性质,许多不同的代码部分共享成为麻烦,我强烈反对这种方法。

要展开此模板,您必须拥有一个JSON配置文件,该文件可以覆盖要连接的端口和服务器。 require非常容易使用,而不是使用此处的默认值。这也意味着当您将应用程序部署到另一个系统时,不必使用任何实际代码。

您还可以展开包装器模块,以便在小池中保持活动连接,以避免关闭,然后立即打开新的连接。稍微关注一下,你甚至可以检查这些句柄是否处于理智状态,例如没有卡在MULTI事务的中间,然后再将它们移出,执行PING并进行测试立即回应。这也消除了陈旧/死亡的联系。