AWS Lambda - 如何在发生故障时停止重试

时间:2018-03-02 12:42:17

标签: amazon-web-services aws-lambda

我知道当一个Lambda函数失败时(例如当有一个超时)时,它会再次尝试再运行该函数3次。有什么方法可以避免这种行为吗?我一直在阅读文档,但没有发现任何相关内容。

谢谢!

9 个答案:

答案 0 :(得分:15)

当它是未处理的失败(你没有捕获的错误)或者你处理它但仍然告诉Lambda重试时重试(例如在Node中,当你调用{{1使用非null的第一个参数)。

要阻止它重试,您应确保处理任何错误,并通过返回非错误(或在Node中调用callback()告诉Lambda您的调用成功完成。

要执行此操作,您可以使用try-catch包围处理函数的整个主体。

callback(null, <any>)

至于因超时而导致的失败,你可以做些事情。

如果你的处理程序超出外部,你的代码通常会出现问题(例如,数据库配置不正确等)。

如果在调用期间你的处理程序超出内部,你可以做些什么。

  • 如果是HTTP请求,您应该将请求的超时设置为短于Lambda的超时,这样它将正常失败并且您可以捕获它。
  • 如果是数据库连接,您可以使用您正在使用的库设置超时。
  • 如果你的逻辑超时,你可以升级Lambda以使用更高的内存CPU来加快速度。您还可以检查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') } } 以了解Lambda是否即将超时,以便您可以提前处理它。

答案 1 :(得分:9)

没有办法禁用Lambda函数的重试行为。

我建议有两种方法可以解决这个问题:

  1. 使您的Lambda能够正确处理重试案例。您可以使用在重试Lambda时相同的context.AwsRequestId(或相应字段)。
  2. 将Lambda放入状态机(使用AWS Step Functions)。您只能禁用重试。
  3. This blog post我写过的内容给出了更为一般的解释。

答案 2 :(得分:7)

如果您异步调用函数,请在Console下的Function configuration中,修改Retry attempts

{{0}}

答案 3 :(得分:7)

November 2019起,可以将重试计数设置为0。

这意味着不会在出错时重试lambda。

答案 4 :(得分:3)

如前所述,该功能最近已添加。要使用cloudformation实现此行为,您将同时需要AWS::Lambda::VersionAWS::Lambda::EventInvokeConfig

  MyLambda:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: my-lambda-dev
      ...

  MyLambdaVersion:
    Type: AWS::Lambda::Version
    Properties:
      FunctionName: !Ref MyLambda

  MyLambdaAsyncConfig:
    Type: AWS::Lambda::EventInvokeConfig
    Properties:
      FunctionName: !Ref MyLambda
      MaximumRetryAttempts: 0
      Qualifier: !GetAtt MyLambdaVersion.Version

答案 5 :(得分:0)

如果使用python,则还需要将代码放入try / catch块中,但是不会有回调。例如:

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

由于已解决错误,Lambda将不会重试。

答案 6 :(得分:0)

使用以下代码识别并在发生故障时停止重试。

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

您可以详细了解here

答案 7 :(得分:0)

我通过放置以下代码行实现了这一点:

callback(null,“ message”);

进入我的功能,例如下面的DynamoDB更新。如果发生错误,则无需在最后重试数小时,而是在if / else外的此回调将停止重试。

dynamodb.updateItem(params, function(err, data){
                 if (err) {
                    console.log(err)
                    callback(err, data)
            } else {
                 console.log(data);
                 callback(null, data);
           }
           callback(null, "message");
        });

答案 8 :(得分:-1)

如果您使用的是Python,建议您遵循this thread

如果您使用的是Java,请在handleRequest方法内添加以下行:

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