AWS Lambda - Как остановить повторные попытки при сбое

Я знаю, что когда функция Lambda не работает (например, когда есть тайм-аут), она пытается снова запустить функцию еще 3 раза. Есть ли способ избежать такого поведения? Я читал документацию, но не нашел ничего об этом.

Спасибо!

Ответ 1

Нет способа отключить повторное поведение лямбда-функций.

Я предлагаю два варианта решения этой проблемы:

  1. Сделайте ваш Lambda способным правильно обрабатывать случаи повторных попыток. Вы можете использовать context.AwsRequestId (или соответствующее поле), которое будет таким же, когда повторяется лямбда.
  2. Поместите свою лямбду в конечный автомат (используя пошаговые функции AWS). Вы можете только тогда отключить повторные попытки.

Этот пост в блоге, который я написал, дает более общее объяснение.

Ответ 2

Он повторяет попытку, когда это необработанный сбой (ошибка, которую вы не поймали), или если вы ее обработали, но все же сказали Lambda повторить попытку (например, в узле, когда вы вызываете callback() с ненулевым первым аргументом).

Чтобы остановить его от повторной попытки, вы должны удостовериться, что любая ошибка обрабатывается, и вы указываете Lambda, что ваш вызов завершен успешно, возвращая не-ошибку (или в Node, вызывающий callback(null, <any>).

Для этого вы можете приложить весь элемент функции обработчика с помощью try-catch.

module.exports.handler(event, context, callback) {
  try {
    // Do you what you want to do.
    return callback(null, 'Success')
  } catch (err) {
    // You probably still want to log it.
    console.error(err)
    // Return happy despite all the hardships you went through.
    return callback(null, 'Still success')
  }
}

Что касается сбоев из-за тайм-аутов, есть вещи, которые вы можете сделать.

Если он выходит за пределы вашего обработчика, обычно что-то не так с вашим кодом (например, некорректная конфигурация базы данных и т.д.), На которую вы должны смотреть.

Если время ожидания внутри обработчика во время вызова, есть кое - что вы можете с этим поделать.

  • Если это HTTP-запрос, вы должны установить тайм-аут запроса короче, чем ваш тайм-аут Lambda, таким образом он будет неудачно, и вы сможете его поймать.
  • Если это соединение с базой данных, вы можете установить тайм-аут, используя библиотеку, которую используете.
  • Если это ваша логика, что время ожидания, вы можете обновить Lambda, чтобы использовать более высокий процессор памяти, чтобы сделать его быстрее. Вы также можете проверить context.getRemainingTimeInMillis() чтобы узнать, context.getRemainingTimeInMillis() ли Lambda к тайм-ауту, поэтому вы можете справиться с ним раньше.

Ответ 3

Если вы используете python, тогда нужно поместить код в блок try/catch, однако обратного вызова не будет. Например:

try:
    do_something()
except Exception as e:
    print('Error: ' + str(e))

Поскольку ошибка была обработана, Lambda не будет повторять попытку.

Ответ 4

Используйте приведенный ниже код, чтобы определить и остановить повторную попытку в случае сбоя.

  exports.handler = (event, context, callback) => {
      context.callbackWaitsForEmptyEventLoop = false;
      let lastReqId;
      if (lastReqId == context.awsRequestId) {
        console.log("Lambda auto retry detected. Aborting");// you can write your own logic to decide what to do with the failure data
        return context.succeed();
      } else {
        console.log("new context");
        lastReqId = context.awsRequestId;
      }
    };

Вы можете прочитать больше об этом здесь

Ответ 5

Если вы используете Python, я рекомендую вам следовать этой теме.

Если вы используете Java, внутри метода handleRequest добавьте следующие строки:

ClientConfiguration config = new ClientConfiguration();
config.setMaxErrorRetry(0);