如何执行 lambda 函数的 N 个并发实例



我正在尝试查看是否可以在我的代码中调用 lambda 函数的 N 个实例。这是我在 EC2 实例上执行的简单代码:

const AWS = require('aws-sdk');
const https = require('https');
const sslAgent = new https.Agent({
keepAlive: true,
maxSockets: 50,
rejectUnauthorized: true,
});
sslAgent.setMaxListeners(0);
AWS.config.update({
region: 'us-east-1',
httpOptions: {
agent: sslAgent,
},
});
const lambda = new AWS.Lambda();
function call() {
return lambda.invoke({
FunctionName: "test",
Payload: JSON.stringify({
wait: 5000,
}),
}).promise();
}
(async () => {
let start = Date.now();
const promises = [...Array(200).keys()].map(i => {
return call(new Date(Date.now()).toISOString())
.then(data => {
console.log(`Success (${i})`);
})
.catch(err => {
console.log(`Error (${i}): ${err}`);
});
});
await Promise.all(promises);
let end = Date.now();
console.log((new Date(end - start).toISOString()).substr(11, 12));
})();

如您所见,此代码将执行一个名为test的 lambda 函数 200 次。然后它将等待所有这些返回,然后测量需要多长时间(如果您有兴趣,则需要 20.883 秒 - 是的,我知道它太长了!

然后在服务器端,我有这个testlambda函数:

exports.handler = async (event, context, callback) => {
// TODO implement
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Lambda!'),
};
return new Promise((resolve) => {
setTimeout(() => {
callback(null, response);
resolve();
}, event.wait);
});
};

非常简单明了,只要收到请求,它就会等待,然后再返回。

现在,问题是我执行了这个场景,这导致只有 50 个并发执行 lambda 函数。我根据CloudWatch上生成的日志知道这一点。在那里我可以看到 lambda 函数的每个实例都处理了 4 个请求(因此之前报告的 20 秒 - 4 次顺序执行 * 5 秒等待等于 20 秒)。

我可以验证我没有为 lambda 函数设置任何并发限制,并且它在默认选项Use unreserved account concurrency上。此外,该帐户相当空,我远远落后于1000的限制。

我的问题是;为什么我不能同时执行所有 200 个请求,为什么我面临限制?

许多 AWS 开发工具包服务的默认执行程序池大小为 50。由于您也在使用 AWS 开发工具包,因此看起来这是相同的问题。您可以尝试多次并行运行相同的脚本,我认为您不应该看到相同的 50 次调用限制。

您可以使用如下所示配置最大套接字大小

var https = require('https');
var agent = new https.Agent({
maxSockets: 200
});
const lambda = new AWS.Lambda({
httpOptions:{
agent: agent
}
});

AWS 论坛上的类似问题: https://forums.aws.amazon.com/thread.jspa?threadID=286655

最新更新