连接到 EC2 实例上的 redis 时连接被拒绝

Connection refused when connecting to redis on EC2 instance

我正在尝试通过 lambda 函数连接到 EC2 实例上的本地 redis 数据库。但是,当我尝试执行代码时,我在日志中收到以下错误

{
    "errorType": "Error",
    "errorMessage": "Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED 127.0.0.1:6379",
    "code": "ECONNREFUSED",
    "stack": [
        "Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED 127.0.0.1:6379",
        "    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1106:14)"
    ],
    "errno": "ECONNREFUSED",
    "syscall": "connect",
    "address": "127.0.0.1",
    "port": 6379
}

安全组有以下条目

Type: Custom TCP Rule
Port: 6379
Source: <my security group name>

Type: Custom TCP Rule
Port: 6379
Source: 0.0.0.0/0

我的 Lambda 函数具有以下代码。

'use strict';
const Redis = require('redis');

module.exports.hello = async event => {
  var redis = Redis.createClient({
      port: 6379,
      host: '127.0.0.1',
      password: ''
    });

  redis.on('connect', function(){
    console.log("Redis client conected : " );   
  });

  redis.set('age', 38, function(err, reply) {
    console.log(err);
    console.log(reply);
  });

  return {
    statusCode: 200,
    body: JSON.stringify(
      {
        message: 'The lambda function is called..!!',
        input: event,
        redis: redis.get('age')
      },
      null,
      2
    ),
  };

};

请让我知道哪里出错了。

首先,您的 lambda 尝试连接到本地主机,因此这将不起作用。您必须放置 Redis 实例的 public 或私有 IP。

但是,您仍然需要确保这些事情

  • 应与您的 EC2 实例位于同一 VPC 中
  • 应允许安全组中的出站流量
  • 分配子网
  • 您的实例允许lambda连接安全组中的Redis
const redis = require('redis');
const redis_client = redis.createClient({
    host: 'you_instance_IP',
    port: 6379
});

    exports.handler = (event, context, callback) => {
        redis_client.set("foo", "bar");

        redis_client.get("foo", function(err, reply) {
            redis_client.unref();
            callback(null, reply);
        });
    };

你也可以看看这个how-should-i-connect-to-a-redis-instance-from-an-aws-lambda-function

在 Linux Ubuntu 服务器 20.04 LTS 上,我在重启 EC2 服务器后看到了类似的错误,对于我们的用例,它通过连接 nodeJs 应用程序的 cron 作业运行 express 应用程序(已安装使用 nvm)使用 passport.js 在 Redis 中使用会话:

Redis 错误:错误:Redis 连接到 127.0.0.1:6379 失败 - 连接 ECONNREFUSED 127.0.0.1:6379 在 TCPConnectWrap.afterConnect [完成时] (net.js:1144:16) { 错误号:'ECONNREFUSED', 代码:'ECONNREFUSED', 系统调用:'connect', 地址:'127.0.0.1', 端口:6379 }

因为我的 nodeJs 应用程序是 运行 作为 Ubuntu 用户我需要使该路径可用,所以为我解决了这个问题,是通过以下方式添加到 /etc/crontab 中的路径:

sudo nano /etc/crontab 把原来的路径注释掉就可以了(我原来的PATH设置为:PATH=/usr/local/sbin:/usr/local/bin:/sbin: /bin:/usr/sbin:/usr/bin ) 并附加您可能需要引用的 bin 的位置,格式为:

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/home/ubuntu/.nvm/versions/node/v12.20.0/bin

错误对我来说消失了

// redisInit.js

const session = require('express-session');
const redis = require('redis');
const RedisStore = require('connect-redis')(session);

const { redisSecretKey } = process.env;

const redisClient = redis.createClient();

redisClient.on('error', (err) => {
    console.log('Redis error: ', err);
});

const redisSession = session({
    secret: redisSecretKey,
    name: 'some_redis_store_name',
    resave: true,
    saveUninitialized: true,
    cookie: { secure: false },
    store: new RedisStore(
        {
            host: 'localhost', port: 6379, client: redisClient, ttl: 86400
        }
    )
});

module.exports = redisSession;