Lambdas在一段时间后停止调用

时间:2018-10-26 23:56:13

标签: aws-lambda serverless-framework

这是我的设置:

一个 Python 3.6 lambda函数,我想在某个并发级别(例如10)保持预热状态。 lambda的初始化非常痛苦,以至于我不想随意给访问者造成这种代价。我称这些lambda为“工人”

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

我遵循了[https://www.jeremydaly.com/lambda-warmer-optimize-aws-lambda-function-cold-starts/]上的指南,即:

  • ping的频率不要超过每5分钟
  • 直接调用该函数(即不要使用API​​ Gateway调用它)
  • 传递可以这样识别的测试有效载荷
  • 创建在不运行整个功能的情况下进行相应答复的处理程序逻辑

这是一个问题:这在几分钟内效果很好。然后,当我查看日志时,我开始从我的worker lambda调用中获取超时。超时很快接管了加热器启动的所有调用。

现在,没有任何工人lambda受到预热了。但是,根据Cloudwatch事件Cron时间表,升温者继续尝试遭受100%的超时。最终,Lambda完全停止尝试启动我的工人Lambda。感觉就像Lambda的状态混乱一样。恢复的唯一方法是重新部署lambda。这使我又有了一个预热的lambda的工作时间。

问题:

  • 如何了解为什么我的工人lambda开始超时,然后变得完全无响应?
  • “并发执行”的定义是什么?在主要Lambda仪表板上,它向我显示了这些图表。但是,它的并发执行次数似乎是我要求的两倍以上。

enter image description here 这是预热lambda代码(节点):

// 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\`);

}

这是worker lambda(Python):

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

1 个答案:

答案 0 :(得分:0)

这是变暖的(节点)lambda束手无策,尽管所有日志都指向了工作(Python)lambda。设置context.callbackWaitsForEmptyEventLoop = false后,问题消失了。