AWS Lambda SDK – TooManyRequestsException

我有大约50个AWS Lambda函数,我有一个吞吐任务来部署它,脚本压缩函数并将其上传到S3,然后使用Lambda JS SDK我称这个任务来创build/更新函数:

gulp.task('upload', function (callback) { var AWS = require('aws-sdk'); var lambda = Promise.promisifyAll(new AWS.Lambda(), { filter: function (name) { return name.indexOf('Async') === -1; } }); var promises = require('./lambda-config.js').lambda.map(function (lambdaConfig) { return lambda.getFunctionConfigurationAsync({ FunctionName: lambdaConfig.FunctionName }).then(function () { return lambda.updateFunctionCodeAsync({ FunctionName: lambdaConfig.FunctionName, S3Bucket: lambdaConfig.Code.S3Bucket, S3Key: lambdaConfig.Code.S3Key }); }).catch(function () { return lambda.createFunctionAsync(lambdaConfig); }); }); Promise.all(promises).then(() => callback()).catch(callback); }); 

我得到TooManyRequestsException error ,压缩的大小是13MB,解压缩的版本是50MB。 我不认为大小是问题,但并发的SDK调用。

我在哪里可以find关于可以为AWS SDK执行多less个并发呼叫的信息? 你怎么build议我可以解决TooManyRequestsException error ? 代码示例表示赞赏。

看起来这里的并发性有问题。 我有同样的问题,保存许多承诺,然后用Promise.all执行它们

这是通过使用具有类似function的Bluebird Promise库(Promise.map)来解决的,该库也处理并发。

代码将是这样的事情:

 const Promise = require('bluebird'); Promise.map(arrayWithLambdas, lambda => { //Deploy each lambda }, { concurrency: 5}) // Control concurrency .then(() => { // Handle successful deploy of lambdas }) .catch(() => { // Handle unsuccessful deploy of lambdas }) }; 

zip的大小似乎不是一个问题(见http://docs.aws.amazon.com/lambda/latest/dg/limits.html )。

当超过AWS授权该帐户的Lambda进程数时,我收到了TooManyRequestsException。 以下是围绕这种限制要考虑的一些事情:

  1. 您从约100的限制开始。有关详细信息,请参阅https://aws.amazon.com/lambda/faqs/ 。 据我所知,这意味着最好的情况下,如果没有其他的事情发生,你最多只能有100个Lambda进程在任何时候运行。

  2. Lambda进程结束的时间与结束进程记入您的限制的时间之间存在滞后。 我不确定是否有明确的指导,这段时间是多久; 根据我的经验,从几秒到一分钟左右, 所以如果你有一个使用50个lamda的进程,每个lambda需要60秒的运行时间,那么最好的情况是100个限制,你可以每分钟运行一次这个进程,但实际上它可能会比这个限制多一点。

  3. 如果您向Amazon发送服务限制增加请求(支持 – >创build个案 – >服务限制增加),则可以增加限制。 您将不得不提供每秒请求数量,请求持续时间等信息。

  4. 非常重要:Lambda进程可能会自动重试 – 请参阅https://aws.amazon.com/lambda/faqs/,esp “如果我的帐户超出了并发执行的默认限制限制,会发生什么? 和“如果我的Lambda函数在处理事件期间失败,会发生什么?”。 这意味着如果你已经超出了你的限制,而且你还在继续testing,那么你可能会有一些积压的进程仍然在重试(并使用你的限制)。

基于此,您可能需要执行以下操作:

  1. 自己pipe理重试,不要使用Amazon的内置重试机制,尤其是对于任何交互式和/或用于testing的目的。 例如在Node:

     var lambda = new AWS.Lambda({ region: REGION, maxRetries:0, .... }); 

    然后你可以使用如下的东西来pipe理:

     lambda.invoke(lambda_params, function(err, obj){ if(err){ if(err.toString().match(/TooManyRequestsException/)) ... 
  2. 如果你想确保停止任何可能仍然失控的Lambdas(不pipe是因为重试还是因为你的代码中有bug),删除你的lambda函数。 例如从控制台: aws lambda delete-function --function-name my_outofcontrol_func

  3. 在尝试缩放之前,大量使用testingfunction(AWS Dashboard – > Lambda – >select您的function – >testing)。 日志也是有用的,所以如果你为一个testing调用50个lambdaexpression式,你可以去日志,看看这50个lambdaexpression式发生了什么。

  4. 当您需要扩展时,请提前从亚马逊请求。 这将需要几天,对我和其他我听说过的,他们总是想给你比你要求的less。 如果你有已经使用过你已有的能力的历史,这会有所帮助。 要小心,一旦你达到了1000个节点,在通过免费层面开始支付每一次使用费用(更多理由做了很多#3)之前,不需要进行大量的testing。