AWS Lambda завершает работу перед отправкой сообщения в SQS - PullRequest
2 голосов
/ 23 мая 2019

Я запускаю лямбду Node.JS на AWS, которая отправляет сообщение в SQS.По какой-то причине функция обратного вызова SQS выполняется только один раз каждые пару вызовов .Похоже, что поток, выполняющий лямбду, заканчивает выполнение (потому что это не синхронный вызов SQS и также не может вернуть Future), и поэтому лямбда не «остается в живых» для выполнения обратного вызова.

Как я могу решить эту проблему и заставить лямбду ждать выполнения обратного вызова SQS?

Вот мой лямбда-код:

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 Ответ

1 голос
/ 23 мая 2019

Вы должны либо придерживаться подхода, основанного на обратном вызове, либо обещать подход, основанный на. Я рекомендую вам использовать последний:

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
  }
};

P.S. Создание классов aws в обработчике не является хорошей идеей в лямбда-среде, поскольку увеличивает время холодного запуска. Лучше убрать действие new AWS.SQS(...) из обработчика и AWS.config.update(), так как эти действия будут выполняться при каждом вызове обработчика, но вам действительно нужно, чтобы они выполнялись только один раз.

...