AWS Lambda:任务超时

Posted

技术标签:

【中文标题】AWS Lambda:任务超时【英文标题】:AWS Lambda: Task timed out 【发布时间】:2017-09-20 12:35:12 【问题描述】:

我的学校项目要求我们编写一个在 AWS Lambda 中运行的 Java 代码。它应该获取特定 URL 的源代码,然后将其上传到 S3 存储桶。 Java 代码应该在 AWS Lambda 上运行。

我得到了 Java 中 String 变量的源代码。然后我有 while 循环尝试将字符串写入 /tmp 目录中的文件。然后将文件上传到 S3。

一切正常,但我被一个特定的 URL 卡住了。我已经跟踪到这一点:

try 
    BufferedWriter out = new BufferedWriter(new FileWriter("/tmp/url.txt"));
    out.write(source_code);  //Replace with the string 
    //you are trying to write  
    out.close();

catch (IOException e) 
    System.out.println("Exception ");

最奇怪的是,当我在本地测试代码时,一切正常。在我的计算机上的 /tmp 目录中创建文件,然后将其上传到 S3 存储桶。但是,当我在 Lambda 中运行代码时,出现以下错误:

Task timed out after 15.00 seconds

知道为什么 Lambda 在这种特定情况下无法将文件写入其临时目录并且它可以与其他人一起使用吗?

【问题讨论】:

this 有帮助吗? (只是在黑暗中拍摄,我真的不知道) 【参考方案1】:

Amazon Lambda 旨在用作响应事件的事件驱动系统。流程是:

某处发生触发 Lambda 的事情(例如,上传到 Amazon S3、数据进入 Amazon Kinesis 流、应用程序直接调用 Lambda 函数) Lambda 函数已创建,来自触发事件的数据已传递 Lambda 函数运行

Lambda 函数的最大执行时间限制为 15 分钟(最近从最初的 5 分钟超时时间增加)。 实际限制是在创建 Lambda 函数时配置的。限制已经到位,因为 Lambda 函数旨在小而快,而不是大型应用程序。

您的错误消息显示Task timed out after 15.00 seconds。这意味着 AWS 在运行时间达到 15 秒后故意停止任务。它与函数当时正在做什么无关,也与正在处理的文件无关。

解决方法:增加 Lambda 函数配置页面上的超时设置。

【讨论】:

我同意@John。您需要增加 lambda 超时限制,最多可增加 5 分钟。您的代码处理时间超过 15 秒。 这就是我尝试过的,我已将超时时间增加到 2 分钟,但仍然没有运气。我的 Lambda 函数每 15 分钟运行一次,它由 Jenkins 触发。我不明白什么时候在本地运行,它工作得很好,但是在 Lambda 上,它失败了。一个特定站点也会发生这种情况,其他站点都很好,并且 Lambda 可以正确处理它。另外,您认为最好不要在 /tmp 目录中存储任何内容并将其直接从内存上传到 S3 存储桶吗?非常感谢。 现在您已将超时时间增加到 2 分钟,您是否收到“120 秒后超时”消息?如果是这样,这意味着事情还没有完成。您应该记录尽可能多的信息,然后使用日志来找出一直在花费的时间。 (这就是编程的乐趣!)上传文件后一定要从/tmp 删除文件,否则空间不足。在上传之前记录文件的大小会很好,所以如果它失败了,你就会知道它试图做什么。 非常感谢约翰的所有回复,非常感谢。我将尝试详细说明。我的程序将 URL 的源代码获取到字符串中,然后将其与 /tmp 目录中已经存在的文件(之前运行的源代码)进行比较,如果有变化,则将其上传到 S3 存储桶。所以 /tmp 存储最新的源代码文件以供比较。我想知道这是否是一个好习惯?我一步一步地跟踪问题,程序在尝试写入文件时卡住了。我不明白的一点是,如果只有一个站点失败。 是的,即使超时时间增加,仍然会收到相同的消息。但我认为 120 秒太长了,因为通常需要 7 秒左右。【参考方案2】:

您似乎将超时配置为 15 秒。您可以按照此屏幕截图中的说明增加超时,并且根据 lambda 设置,它允许您执行的最长时间为 15 分钟。

【讨论】:

【参考方案3】:

在我的情况下,当任务在本地运行良好但在 Lambda 上超时时,这是因为我需要增加分配给 Lambda 实例的内存。

【讨论】:

增加分配的 RAM 将成比例地增加 CPU(以及您在一定程度上分享的网络带宽),因此您的函数运行得更快,完成得更快。 同样,基于 Node.JS 的 AWS Lambda 函数超时,没有打印出任何日志。我首先想到的是导入随机库的问题,结果是内存问题。增加内存分配解决了这个问题。运行函数后检查“使用的最大内存”有助于找到解决方案。【参考方案4】:

对于那些在使用async 时遇到此超时问题的人,请注意异步函数的处理程序的模式是不同的。

而不是

exports.handler = function (event, context, callback) 
    callback(null, 
        statusCode: 200,
        body: JSON.stringify(/* return stuff here */)
    );
;

这是

exports.handler = async function (event, context) 
    return 
        statusCode: 200,
        body: JSON.stringify(/* return stuff here */)
    ;
;

【讨论】:

希望我能给你一百万个赞。你的暗示让我很开心。非常感谢! 谢谢。只想把这个留在这里docs.aws.amazon.com/lambda/latest/dg/nodejs-handler.html【参考方案5】:

您可以将 lambda 函数的超时时间增加到 15 分钟,或者您可以增加 lambda 函数的内存分配以使其更快。您可以将内存增加到 3008MB。其最小值为 128MB。 如果你有,它是这样的: 分配给您的 lambda 函数的大内存分配比执行该 lambda 函数所需的时间更少,反之亦然。每次执行 lambda 函数时,大内存分配会花费更多。您需要计算超时时间和分配给 lambda 函数的内存的平衡。不要只分配大块内存,以便您可以很快看到结果,分析成本和您的需求。 附上一张图,其中更改超时和内存分配。转到您的 Lambda 函数 -> 配置 -> 基本设置以查找设置。

【讨论】:

嘿 lalit,感谢您的回答,但请提供一些上下文和解释。根据该用户的问题和描述,他/她显然对此很陌生,因此不知道在数据传输或内存分配期间遇到超时以及为什么会发生这种情况。因此,请考虑到这一点,并在您的答案中添加更多详细信息。 我已在答案中添加了详细信息。 非常感谢,我有一个图像压缩器 lambda,内存为 128mb,超时时间为 3 秒。在升级到 256mb 和 5 秒超时后,它一直无法处理 png 文件,一切正常!【参考方案6】:

我通过将 AWS-SDK 放在函数体之外解决了这个问题:

var AWS = require("aws-sdk");
exports.handler = function(event, context, callback)

//var AWS = require("aws-sdk"); //Error: Task timed out after 3.00 seconds
var docClient = new AWS.DynamoDB.DocumentClient();
console.log("Lambda starts");
...

【讨论】:

这是一个很好的提示。有关更多详细信息 - 这将有两个原因:1) 现在仅在 lambda 实例启动时发生 require,而不是每次 lambda 调用,因此您可以在不进行冷启动时节省一些时间。 2)当 lambda 实例启动(冷启动)时,它有额外的 CPU 用于处理函数体之外的事情,所以它比其他情况发生得更快。 经过数小时的调试,这救了我,一个非常简单的修复!【参考方案7】:

最近,我正在开发一个 POC 以使用 AWS Lambda 函数。我也面临同样的问题(任务在 15.01 秒后超时)。我只是增加了内存分配,它解决了这个问题。美丽是我可以在几秒钟内得到回应。所以,我认为错误几乎没有误导性。它应该提供失败的确切根本原因。

【讨论】:

错误如何误导?它超时了。时期。如果您在一台非常低调的机器上执行繁重的任务,那是另一回事。此外,内存使用情况始终在 CloudWatch 日志中无缝可用。如果你阅读日志,你可以判断你是否应该增加分配的内存。 这对我有用。似乎您基本上有两种方法可以解决此问题:增加内存分配或增加执行超时限制。 @ThalesMinussi 我同意 Pankaj 案例中的错误不会产生误导,但是,即使报告的内存远小于预置内存,增加 lambda 的内存通常也是值得的。假设您有 1 GB 的预置内存,报告称该功能只需要 200 MB。您可能会想“哦,不妨将预配的内存减少到 500 MB”——但事实上,这不仅仅是内存的问题,看起来,配置越高,您也可以获得更高层的 CPU。例如。我的函数使用 250-350 MB,如果我分配 1GB、2GB 或 3GB 内存,响应时间会有很大差异。 是的,它写在设置下:“你的函数分配的CPU与配置的内存成正比。” 虽然在某些情况下增加 RAM 会有所帮助,但不能保证在这里是一种解决方案。想象一个场景,其中 Lambda 函数进行远程 API 调用并等待响应。如果远程服务器花费的时间超过 Lambda 函数超时时间,那么没有多少 RAM 可以帮助您。【参考方案8】:

我遇到了同样的问题,但它是间歇性发生的。我在使用 Insights n XRay 进行调试方面浪费了更多时间,但没有从中得到任何东西。

最后我尝试了一件事,我的 VPC 中有 2 个子网,私有和公共。 所以我只保留了私有子网并删除了另一个。

瞧!

它不再失败了。但是我仍然不知道原因,会继续发布。 如果可行,请尝试使用单个子网运行 lambda。

【讨论】:

谢谢!我有完全相同的问题。我也不明白原因,但保留私有子网确实起到了作用!【参考方案9】:

首先,为什么要写入/tmp/?您写入执行 Lambda 函数的同一位置?

但是,更好的做法是,如果您想将字符串写入 S3 文件,那么您可以创建一个 S3Object 并将其直接写入 AWS S3。这是一个显示示例的帖子:https://***.com/a/29844224/358013

【讨论】:

/tmp/ 是 lambda 让你写文件的唯一位置 无论是否写入 /tmp/,都需要在长时间运行的 lambda 函数中解决超时问题。这个答案并没有以任何方式解决这个问题! @SyedWaqas 这是一个非常古老的答案,AWS Lambda 的执行方式可能已经发生了变化。答案建议了另一种选择。仅仅因为 OP 试图做某事并不意味着这是正确的方法。

以上是关于AWS Lambda:任务超时的主要内容,如果未能解决你的问题,请参考以下文章

AWS Lambda 任务在 6.00 秒后超时

在将 aws lambda 与 redis 连接时,任务在 23.02 秒后超时错误

AWS Lambda 上的 PhantomJS 总是超时

Lambda NodeJS MySQL 任务超时

AWS lambda 函数在超时错误后停止工作

AWS Lambda 内部的 Parameter Store 请求超时