Aws lambda Lambdas在一段时间后停止调用

Aws lambda Lambdas在一段时间后停止调用,aws-lambda,serverless-framework,Aws Lambda,Serverless Framework,以下是我的设置: 一个Python3.6lambda函数,我希望在某个并发级别(比如10)对其进行预热。lambda的初始化已经够痛苦的了,我不想随意给访问者造成这样的代价。我称这些羔羊为“工人” 节点lambda函数,每5分钟运行一次,尝试预热10个实例。其中9个使用事件调用类型,1个使用RequestResponse。在任何时候,只有一个或零个lambda在运行。我称之为“温暖” 我遵循了[]的指导方针,即: 不要超过每5分钟ping一次 直接调用函数(即不使用API网关调用) 通过可识别

以下是我的设置:

一个Python3.6lambda函数,我希望在某个并发级别(比如10)对其进行预热。lambda的初始化已经够痛苦的了,我不想随意给访问者造成这样的代价。我称这些羔羊为“工人”

节点lambda函数,每5分钟运行一次,尝试预热10个实例。其中9个使用事件调用类型,1个使用RequestResponse。在任何时候,只有一个或零个lambda在运行。我称之为“温暖”

我遵循了[]的指导方针,即:

  • 不要超过每5分钟ping一次
  • 直接调用函数(即不使用API网关调用)
  • 通过可识别的测试有效载荷
  • 创建相应响应的处理程序逻辑,而不运行整个函数
这里有一个问题:这在几分钟内效果很好。然后,当我查看日志时,我开始从我的worker lambda调用中获取超时。超时会很快接管加热器尝试启动的所有调用

现在,不再对工作Lambda进行预热。但是,按照Cloudwatch事件cron时间表,加热器继续尝试,遭受100%超时。最后,Lambda停止尝试启动我的工作Lambda。感觉Lambda的某些方面状态混乱。恢复的唯一方法是重新部署Lambda。这给我带来了另一个预热lambdas工作小时数

问题:

  • 我如何了解为什么我的员工Lambda开始超时,然后变得完全不响应
  • “并发执行”的定义是什么?在Lambda主仪表板上,它向我显示了这张图表。然而,它的并发执行数量似乎是我请求的两倍多
以下是预热lambda代码(节点):


虽然所有日志都指向worker(Python)lambda,但更温暖的(节点)lambda仍处于混乱状态。在设置context.callbackaitsforemptyeventloop=false后,问题消失了。

“我开始从我的worker lambda调用中获取超时”…这需要定义。您从中获取超时”他们…在哪里观察到?这看起来像什么?它看起来像“{TimeoutError:连接在ClientRequest的30000ms后超时。(/var/runtime/node_modules/aws sdk/lib/http/node.js:83:34)”,在加热器的Cloudwatch日志中。这种情况一直发生,直到我重新部署该功能。然后它将再次工作,大约一个小时。因此,联系Lambda服务API时超时。最初的印象是:您正在VPC中运行Lambda函数,但两个子网不完全相同……与Lambda函数关联的子网之一on没有正确配置为使用NAT网关作为默认路由。很好的猜测,但我们没有使用VPC:-)此外,超时完全没有大约一个小时,然后开始发生。之后,它有点像荷兰榆树病,我必须将工作lambda视为死亡并重新部署。解决了,谢谢@Michael sqlbot!
// warmer
"use strict";

/** Generated by Serverless WarmUP Plugin at ${new Date().toISOString()} */
const aws = require("aws-sdk");
aws.config.region = "${this.options.region}";
const lambda = new aws.Lambda({httpOptions: {timeout: 60000}});
const functionNames = ${JSON.stringify(functionNames)};
const delay = ms => new Promise(res => setTimeout(res, ms))
const concurrency = 10;
module.exports.warmUp = async (event, context, callback) => {
  console.log("Warm Up Start");
  const invokes = await Promise.all(functionNames.map(async (functionName) => {

    let invocations = [];

    try {
      for(let i=1;i <= concurrency;i++){
          let params = {
            FunctionName: functionName,
            InvocationType: (i===concurrency)?'RequestResponse': 'Event',
            LogType: 'None',
            Qualifier: process.env.SERVERLESS_ALIAS || "$LATEST",
            Payload: JSON.stringify({
              source: 'serverless-plugin-warmup',
              '__WARMER_INVOCATION__': i,
              '__WARMER_CONCURRENCY__': concurrency,
              '__WARMER_REQUESTED__': new Date().toISOString(),
            })
          };

          invocations.push(lambda.invoke(params).promise())
      }
      return await delay(75).then(Promise.all(invocations.map(p => p.catch(e => e)))
        .then(results => console.log('results', results))
        .catch(e => {
          console.log(e);
          return e;
        }
        ))
    } catch (e) {
      console.log(\`Warm Up Invoke Error: \${functionName}\`, e);
      return false;
    }
  }));

  console.log(\`Warm Up Finished\`);

}
    source = event.get('source')
    if source == 'serverless-plugin-warmup':
        time.sleep(0.05)
        print(event)
        return lambda_gateway_response(200, {"status": "lambda warmup"})