连接到同一 VPC 中的 Redis Elasticache 时 AWS Lambda 超时

AWS Lambda Timeout when connecting to Redis Elasticache in same VPC

尝试从 Lambda 函数发布到 Redis Elasticache,但我继续收到 502 Bad Gateway 响应,Lambda 函数超时。

我已使用同一 VPC 中的 ECS 成功连接到 Elasticache 实例,这让我认为我的 Lambda 的 VPC 设置不正确。我尝试按照本教程 (https://docs.aws.amazon.com/lambda/latest/dg/services-elasticache-tutorial.html) 进行操作,但查看了多个 Whosebug 线程都无济于事。

Lambda 函数:

export const publisher = redis.createClient({
  url: XXXXXX, // env var containing the URL which is also used in the ECS server to successfully connect
});

export const handler = async (
  event: AWSLambda.APIGatewayProxyWithCognitoAuthorizerEvent
): Promise<AWSLambda.APIGatewayProxyResult> => {
  try {
    if (!event.body || !event.pathParameters || !event.pathParameters.channelId)
      return ApiResponse.error(400, {}, new InvalidRequestError());

    const { action, payload } = JSON.parse(event.body) as {
      action: string;
      payload?: { [key: string]: string };
    };

    const { channelId } = event.pathParameters;

    const publishAsync = promisify(publisher.publish).bind(publisher);

    await publishAsync(
      channelId,
      JSON.stringify({
        action,
        payload: payload || {},
      })
    );

    return ApiResponse.success(204);
  } catch (e) {
    Logger.error(e);
    return ApiResponse.error();
  }
};

在故障排除中,我在 Lambda 函数控制台中验证了以下内容:

明明是小事,却绞尽脑汁!

更新 1:

尝试添加一个错误处理程序来记录除主 try/catch 块之外的任何发布问题,但它没有记录任何事情。

publisher.on('error', (e) => {
    Logger.error(e, 'evses-service', 'message-publisher');
  });

还复制了我的 Elasticache 设置:

还有我的 Elasticache 子网组:

还有我的 Lambda VPC 设置:

并且我的 Lambda 具有正确的访问权限:

更新 2:

试图逐字逐句地按照此处的教程 (https://docs.aws.amazon.com/lambda/latest/dg/services-elasticache-tutorial.html) 进行操作,但遇到了同样的问题。没有日志,只有 30 秒后超时。这是测试代码:

const crypto = require('crypto');
const redis = require('redis');
const util = require('util');

const client = redis.createClient({
  url: 'rediss://clusterforlambdatest.9nxhfd.0001.use1.cache.amazonaws.com',
});

client.on('error', (e) => {
  console.log(e);
});

exports.handler = async (event) => {
  try {
    const len = 24;

    const randomString = crypto
      .randomBytes(Math.ceil(len / 2))
      .toString('hex') // convert to hexadecimal format
      .slice(0, len)
      .toUpperCase();

    const setAsync = util.promisify(client.set).bind(client);
    const getAsync = util.promisify(client.get).bind(client);

    await setAsync(randomString, 'We set this string bruh!');
    const doc = await getAsync(randomString);

    console.log(`Successfully receieved document ${randomString} with contents: ${doc}`);

    return;
  } catch (e) {
    console.log(e);

    return {
      statusCode: 500,
    };
  }
};

如果超时,假设 lambda 网络配置良好,您应该检查以下内容:

  • redis SSL 配置:检查 redisS 连接 url 和集群配置(使用 tls: {} 的传输中加密和客户端配置)
  • 使用特定的重试策略配置客户端以避免 lambda 超时和捕获连接问题
  • 检查 VPC acl 和安全组