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

f8rj6qna  于 2023-02-28  发布在  Redis
关注(0)|答案(3)|浏览(226)

尝试从Lambda函数发布到Redis Elasticache,但我仍然得到502 Bad Gateway响应,Lambda函数超时。
我在同一个VPC中使用ECS成功连接到Elasticache示例,这让我认为Lambda的VPC设置不正确。我尝试按照本教程(https://docs.aws.amazon.com/lambda/latest/dg/services-elasticache-tutorial.html)进行操作,并查看了几个StackOverflow线程,但没有效果。
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函数控制台中验证了以下内容:

  • 正确的角色显示在Configuration > Permissions
  • lambda函数可以访问VPC(Configuration > VPCs)、子网和与Elasticache示例相同的SG。
  • SG允许来自任何地方的所有流量。
  • 这确实是Redis连接,使用console.log时,代码会停在这一行:await publishAsync()

我肯定这是件小事,但它伤了我的脑筋!

更新1:

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

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

还复制了我的弹性疼痛设置:

还有我的弹性疼痛子网组:

和我的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,
    };
  }
};
oo7oh9g9

oo7oh9g91#

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

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

06odsfpq2#

我的弹性疼痛也有同样的问题,这里有一些发现-
1.检查使用弹性缓存的客户端连接数和使用的资源
1.检查节点安全组的VPC子网和CIDR
1.尝试增加lambda的TTL,并查看响应Lambda或elasticache的服务花费的时间更多

xwmevbvl

xwmevbvl3#

我也遇到了超时错误,特别是当我的lambda试图 * 读取*/写入 * 数据到我的Redis ElastiCache集群时
在我的例子中,我使用TransitEncryptionEnabled: "true"AuthToken: xxxxx作为我的redis集群。
我的lambda和elastiCache集群都属于同一个"
私有子网 "。我的" securityGroup *"允许流量在所有端口上流动。
设置选项tls: true为我工作。这是一个强制性的设置,如果你有加密在过境启用。
下面是我的代码:

import { createClient } from 'redis';
import config from "../config";

let options: any = {
 url: `redis://${config.REDIS_HOST}:${config.REDIS_PORT}`,
 password: config.REDIS_PASSWORD,
 socket: { tls: true }
};

const redisClient = createClient(options);

希望这个答案对那些在lambda中使用带有"Node-Redis"依赖项的Node.Js的人有所帮助。

相关问题