[英]AWS Lambda - How to stop retries when there is a failure
I know that when a Lambda function fails (for example when there is a time out), it tries to run the function 3 more times again.我知道当 Lambda 函数失败时(例如超时),它会尝试再次运行该函数 3 次。 Is there any way to avoid this behavior?
有什么办法可以避免这种行为? I' have been reading the documentation, but didn't find anyting about this.
我一直在阅读文档,但没有找到任何相关信息。
Thanks!谢谢!
It retries when it is an unhandled failure (an error that you didn't catch) or if you handled it but still told Lambda to retry (eg in Node, when you call callback()
with a non-null first argument).当它是一个未处理的故障(一个你没有捕获的错误)或者如果你处理了它但仍然告诉 Lambda 重试(例如,在 Node 中,当你用一个非空的第一个参数调用
callback()
时),它会重试。
To stop it from retrying, you should make sure that any error is handled and you tell Lambda that your invocation finished successfully by returning a non-error (or in Node, calling callback(null, <any>)
.要阻止它重试,您应该确保处理任何错误,并通过返回非错误(或在 Node 中调用
callback(null, <any>)
告诉 Lambda 您的调用已成功完成。
To do this you can enclose the entire body of your handler function with a try-catch.为此,您可以使用 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')
}
}
As for failures due to timeouts there are things you can do.至于由于超时导致的失败,您可以做一些事情。
If it times out outside of your handler, there's usually something wrong with your code (eg incorrect database config, etc) that you should look at.如果它在您的处理程序之外超时,您应该查看您的代码通常有问题(例如,不正确的数据库配置等)。
If it times out inside your handler during an invocation, there is something you can do about it.如果它在调用期间在您的处理程序中超时,您可以采取一些措施。
context.getRemainingTimeInMillis()
to know if the Lambda is about to timeout, so you can handle it earlier.context.getRemainingTimeInMillis()
以了解 Lambda 是否即将超时,以便您可以更早地处理它。EDITED : It's now possible to change the lambda settings to disable retries (see announcement )编辑:现在可以更改 lambda 设置以禁用重试(参见公告)
Original answer :原答案:
There isn't a way to disable retry behavior of Lambda functions.没有办法禁用 Lambda 函数的重试行为。 I suggest two options to deal with that:
我建议有两种选择来解决这个问题:
Since November 2019 , it is possible to set the retry count to 0.自2019 年 11 月起,可以将重试次数设置为 0。
That means the lambda will not be retried on error.这意味着 lambda 不会在出错时重试。
As mentioned before, this feature has been added lately.如前所述,最近添加了此功能。 To achieve this behaviour using
cloudformation
you will need both an AWS::Lambda::Version
and AWS::Lambda::EventInvokeConfig
:要使用
cloudformation
实现此行为,您将需要AWS::Lambda::Version
和AWS::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
If using python then need to put the code in try/catch block as well however there will be no callback.如果使用 python,则还需要将代码放在 try/catch 块中,但是不会有回调。 For example:
例如:
try:
do_something()
except Exception as e:
print('Error: ' + str(e))
Since the error has been handled, Lambda will not retry.由于错误已得到处理,Lambda 不会重试。
If you are using Python, I recommend you to follow this thread .如果您使用的是 Python,我建议您关注此主题。
If you are using Java, inside handleRequest
method add this lines:如果您使用的是 Java,请在
handleRequest
方法中添加以下行:
ClientConfiguration config = new ClientConfiguration();
config.setMaxErrorRetry(0);
Use below code to identify and stop retry when there is a failure.使用下面的代码来识别并在出现故障时停止重试。
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;
}
};
I achieved this by placing the following line of code:我通过放置以下代码行实现了这一点:
callback(null, "message");回调(空,“消息”);
Into my function such as the below update to DynamoDB.进入我的功能,例如下面对 DynamoDB 的更新。 When there is an error, rather than retrying for hours on end, this callback outside of the if / else will stop the retries.
当出现错误时,不是连续重试几个小时,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");
});
You can also just return true , for example, if you're invoking a Lambda function, using Node.JS.您也可以只返回 true ,例如,如果您使用 Node.JS 调用 Lambda 函数。
I want to stop running the Lambda function, if there's no data.如果没有数据,我想停止运行 Lambda 函数。
So I check for an empty object being returned from the API.所以我检查从 API 返回的空对象。
If it's empty, I return true, and the Lambda is stopped, and the EventBridge is also not re-tried.如果它是空的,我返回 true,Lambda 停止,EventBridge 也不会重试。
This worked for me.这对我有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.