Lambdas 在一段时间后停止调用
Lambdas stop invoking after a period of time
这是我的设置:
A Python 3.6 lambda 函数,我想在某个并发级别(比如 10)保持预热。 lambda 的初始化非常痛苦,我不想随机将此成本强加给访问者。我称这些 lambdas "workers"
一个 Node lambda 函数 每 5 分钟运行一次以尝试预热 10 个实例。其中 9 个使用 Event 调用类型,1 个使用 RequestResponse。此 lambda 运行 在任何时候都只有一个或零个。我称之为 "warmer".
我遵循了 [https://www.jeremydaly.com/lambda-warmer-optimize-aws-lambda-function-cold-starts/] 中的指南,即:
- ping 的频率不要超过每 5 分钟
- 直接调用函数(即不使用API网关调用)
- 传入可识别的测试负载
- 创建无需 运行 整个函数即可进行相应回复的处理程序逻辑
这里有一个问题:这在几分钟内效果很好。然后,当我查看日志时,我开始从我的 worker lambda 调用中获得超时。超时很快接管了 warmer 试图启动的所有调用。
现在,不再预热任何 worker lambda。但是 warmer 继续尝试,在 Cloudwatch 事件 cron 时间表上,遭受 100% 的超时。最后,Lambda 完全停止尝试启动我的 worker lambda。感觉就像 Lambda 的某些方面的状态被打乱了。恢复的唯一方法是重新部署 lambda。预热的 lambda 表达式又给我买了一个小时。
问题:
- 我如何了解为什么我的 worker lambda 开始超时,然后变得完全没有响应?
- "Concurrent Execution"的定义是什么?在主要的 Lambda 仪表板上,它向我展示了这张图表。然而,它的并发执行数似乎是我请求的两倍多。
这是热身 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\`);
}
这是工人 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"})
尽管所有日志都指向 worker (Python) lambda,但较暖的 (Node) lambda 却失控了。设置context.callbackWaitsForEmptyEventLoop = false后问题消失
这是我的设置:
A Python 3.6 lambda 函数,我想在某个并发级别(比如 10)保持预热。 lambda 的初始化非常痛苦,我不想随机将此成本强加给访问者。我称这些 lambdas "workers"
一个 Node lambda 函数 每 5 分钟运行一次以尝试预热 10 个实例。其中 9 个使用 Event 调用类型,1 个使用 RequestResponse。此 lambda 运行 在任何时候都只有一个或零个。我称之为 "warmer".
我遵循了 [https://www.jeremydaly.com/lambda-warmer-optimize-aws-lambda-function-cold-starts/] 中的指南,即:
- ping 的频率不要超过每 5 分钟
- 直接调用函数(即不使用API网关调用)
- 传入可识别的测试负载
- 创建无需 运行 整个函数即可进行相应回复的处理程序逻辑
这里有一个问题:这在几分钟内效果很好。然后,当我查看日志时,我开始从我的 worker lambda 调用中获得超时。超时很快接管了 warmer 试图启动的所有调用。
现在,不再预热任何 worker lambda。但是 warmer 继续尝试,在 Cloudwatch 事件 cron 时间表上,遭受 100% 的超时。最后,Lambda 完全停止尝试启动我的 worker lambda。感觉就像 Lambda 的某些方面的状态被打乱了。恢复的唯一方法是重新部署 lambda。预热的 lambda 表达式又给我买了一个小时。
问题:
- 我如何了解为什么我的 worker lambda 开始超时,然后变得完全没有响应?
- "Concurrent Execution"的定义是什么?在主要的 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\`);
}
这是工人 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"})
尽管所有日志都指向 worker (Python) lambda,但较暖的 (Node) lambda 却失控了。设置context.callbackWaitsForEmptyEventLoop = false后问题消失