代码之家  ›  专栏  ›  技术社区  ›  satyendra

lambda中SES的使用问题

  •  1
  • satyendra  · 技术社区  · 2 年前

    我正在尝试将SES发送函数从我的API服务器移动到lambda函数,SES在API服务器中工作正常,但在lambda中不正常。

    这是设置

    1. 发送SQS消息以触发lambda
    2. Lambda从邮件中提取电子邮件参数(收件人、发件人、主题、电子邮件内容)
    3. 使用SES发送消息

    这是其他相关信息

    1. lambda IAM角色具有完全SES和SQS访问权限
    2. 发件人电子邮件地址已验证(它不在沙盒中)
    3. 标准lambda配置(即未连接到任何VPC)
    4. 这段代码在lambda之外运行良好。
    5. 我将lambda超时从3秒(默认值)增加到60秒。
    6. 我已经验证SES命令的参数是否正确

    这是代码

    import { SESClient, SendEmailCommand } from "@aws-sdk/client-ses";
    
    const sesClient = new SESClient({ region: "us-west-2" });
    
    export const handler = async (event) => {
        event.Records.forEach( async (msg) => {
    
          const args = JSON.parse(msg.body);
    
          const command = new SendEmailCommand ({
            Source: (args.senderEmailAddr || process.env.DEFAULT_SENDER_ADDRESS),
            Destination: { ToAddresses: [args.recipientEmailAddr] },
            Message: {
              Body: { Text: { Data: args.emailContents } },
              Subject: { Data: args.subject },
            },
          });
    
          try {
            const resp = await sesClient.send(command);
    
            console.log('++++++++++++++++++++++++++++++++');
            
            console.log(`Email send response ${resp}`);
            return resp;
          } catch(err) {
            console.log(`Failed to send email - ${err}`);
          } 
        });
    };
    

    lambda在没有任何错误的情况下运行和退出,但是,它从不执行sesClient.send()命令之后的行

    console.log('++++++++++++++++++++++++++++++++');

    它告诉我函数在执行sesClient.send()调用期间终止(如果我将控制台语句放在sesClient.sent()之前,它们会显示在cloudwatch日志中。

    以下是cloudwatch的命令输出

    INIT_START Runtime Version: nodejs:18.v10   Runtime Version ARN: arn:aws:lambda:us-west-2::runtime:e3aaabf6b92ef8755eaae2f4bfdcb7eb8c4536a5e044900570a42bdba7b869d9
    START RequestId: c0a8e260-7149-5934-9246-bf3cc1af54ff Version: $LATEST
    END RequestId: c0a8e260-7149-5934-9246-bf3cc1af54ff
    REPORT RequestId: c0a8e260-7149-5934-9246-bf3cc1af54ff  Duration: 371.10 ms Billed Duration: 372 ms Memory Size: 128 MB Max Memory Used: 95 MB  Init Duration: 587.21 ms
    
    any idea of what I am doing wrong here??
    
    
    1 回复  |  直到 2 年前
        1
  •  2
  •   Piyush Patil    2 年前

    在AWS Lambda中处理异步代码时有一个常见问题。代码中的关键问题是 forEach 具有异步功能。Lambda不等待 for Each 循环在终止之前完成。

    结果是,Lambda函数在启动异步操作后立即完成,而无需等待它们完成。这可能是您在 sesClient.send() 线

    要解决此问题,您应该使用 Promise.all 或者在继续之前等待发送每个电子邮件的循环:

    以下是如何修改处理程序以等待使用发送所有电子邮件 Promise.all :

    export const handler = async (event) => {
        const promises = event.Records.map(async (msg) => {
    
            const args = JSON.parse(msg.body);
    
            const command = new SendEmailCommand({
                Source: (args.senderEmailAddr || process.env.DEFAULT_SENDER_ADDRESS),
                Destination: { ToAddresses: [args.recipientEmailAddr] },
                Message: {
                    Body: { Text: { Data: args.emailContents } },
                    Subject: { Data: args.subject },
                },
            });
    
            try {
                const resp = await sesClient.send(command);
                console.log(`Email send response ${resp}`);
                return resp;
            } catch (err) {
                console.log(`Failed to send email - ${err}`);
            }
    
        });
    
        await Promise.all(promises);
        console.log('++++++++++++++++++++++++++++++++');
    };
    

    现在,Lambda功能将等待所有电子邮件发送完成,并且您应该在发送电子邮件后看到日志。