AWS Lambda 在向 SQS 发送消息之前完成

Posted

技术标签:

【中文标题】AWS Lambda 在向 SQS 发送消息之前完成【英文标题】:AWS Lambda finish before sending message to SQS 【发布时间】:2019-10-09 17:02:16 【问题描述】:

我在 AWS 上运行一个“Node.JS”lambda,它向 SQS 发送消息。 出于某种原因,SQS 回调函数每两次调用只执行一次。看起来运行 lambda 的线程完成了运行(因为它不是对 SQS 的同步调用,也不能返回 Future),因此 lambda 不会“保持活动”以使回调执行。

如何解决此问题并让 lambda 等待 SQS 回调执行?

这是我的 lambda 代码:

exports.handler = async (event, context) => 

// Set the region
AWS.config.update(region: 'us-east-1');

// Create an SQS service object
var sqs = new AWS.SQS(apiVersion: '2012-11-05');
const SQS_QUEUE_URL = process.env.SQS_QUEUE_URL;

var params = 
    MessageGroupId: "cv",
    MessageDeduplicationId: key,
    MessageBody: "My Message",
    QueueUrl: SQS_QUEUE_URL
;

console.log(`Sending notification via SQS: $SQS_QUEUE_URL.`);
sqs.sendMessage(params, function(err, data)    //<-- This function get called about one time every 4 lambda calls
    if (err) 
        console.log("Error", err);
        context.done('error', "ERROR Put SQS");  
     else 
        console.log("Success", data.MessageId);
        context.done(null,'');  
    
);

;

【问题讨论】:

【参考方案1】:

您应该要么坚持基于回调的方法,要么坚持基于承诺的方法。我建议你使用后者:

exports.handler = async (event, context) => 

  // Set the region
  AWS.config.update(region: 'us-east-1');

  // Create an SQS service object
  var sqs = new AWS.SQS(apiVersion: '2012-11-05');
  const SQS_QUEUE_URL = process.env.SQS_QUEUE_URL;

  var params = 
      MessageGroupId: "cv",
      MessageDeduplicationId: key,
      MessageBody: "My Message",
      QueueUrl: SQS_QUEUE_URL
  ;

  console.log(`Sending notification via SQS: $SQS_QUEUE_URL.`);
  try 
      await sqs.sendMessage(params).promise(); // since your handler returns a promise, lambda will only resolve after sqs responded with either failure or success
   catch (err) 
    // do something here
  
;

附:在处理程序中实例化 aws 类在 lambda 环境中不是一个好主意,因为它会增加冷启动时间。最好将 new AWS.SQS(...) 操作移出处理程序和 AWS.config.update(),因为这些操作将在每次调用处理程序时执行,但您确实只需要执行一次。

【讨论】:

谢谢!,我以为它不支持promise()。现在工作:)

以上是关于AWS Lambda 在向 SQS 发送消息之前完成的主要内容,如果未能解决你的问题,请参考以下文章

从 AWS Lambda 读取 SQS 队列

消息发布到 SQS 时如何触发 lambda?

当消息存在于 SQS 队列中时触发 AWS 中的 Lambda 函数

在 SQS 消息触发的 Lambda 上跟踪 AWS API Gateway request_id

从AWS Lambda向SQS队列发送数据时重置连接

在AWS lambda函数上使用pyspark二进制文件,在向驱动程序发送其端口号之前退出错误Java网关进程