【发布时间】:2019-02-13 11:54:51
【问题描述】:
更新
下面的原始测试代码基本上是正确的,但在 NodeJS 中,各种 AWS 服务的设置应与 @Michael-sqlbot 提供的 SDK link 有所不同
// manager
const AWS = require("aws-sdk")
const https = require('https');
const agent = new https.Agent({
maxSockets: 498 // workers hit this level; expect plus 1 for the manager instance
});
const lambda = new AWS.Lambda({
apiVersion: '2015-03-31',
region: 'us-east-2', // Initial concurrency burst limit = 500
httpOptions: { // <--- replace the default of 50 (https) by
agent: agent // <--- plugging the modified Agent into the service
}
})
// NOW begin the manager handler code
在规划一项新服务时,我正在进行一些初步的压力测试。在阅读了每个帐户的 the 1,000 concurrent execution limit 和 initial burst rate(在 us-east-2 中为 500)之后,我期望立即实现至少 500 个突发并发执行。 CloudWatch 的 Lambda 指标的屏幕截图以其他方式显示。 无论我尝试何种参数组合,我都无法超过 51 个并发执行。这是测试代码:
// worker
exports.handler = async (event) => {
// declare sleep promise
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
// return after one second
let nStart = new Date().getTime()
await sleep(1000)
return new Date().getTime() - nStart; // report the exact ms the sleep actually took
};
// manager
exports.handler = async(event) => {
const invokeWorker = async() => {
try {
let lambda = new AWS.Lambda() // NO! DO NOT DO THIS, SEE UPDATE ABOVE
var params = {
FunctionName: "worker-function",
InvocationType: "RequestResponse",
LogType: "None"
};
return await lambda.invoke(params).promise()
}
catch (error) {
console.log(error)
}
};
try {
let nStart = new Date().getTime()
let aPromises = []
// invoke workers
for (var i = 1; i <= 3000; i++) {
aPromises.push(invokeWorker())
}
// record time to complete spawning
let nSpawnMs = new Date().getTime() - nStart
// wait for the workers to ALL return
let aResponses = await Promise.all(aPromises)
// sum all the actual sleep times
const reducer = (accumulator, response) => { return accumulator + parseInt(response.Payload) };
let nTotalWorkMs = aResponses.reduce(reducer, 0)
// show me
let nTotalET = new Date().getTime() - nStart
return {
jobsCount: aResponses.length,
spawnCompletionMs: nSpawnMs,
spawnCompletionPct: `${Math.floor(nSpawnMs / nTotalET * 10000) / 100}%`,
totalElapsedMs: nTotalET,
totalWorkMs: nTotalWorkMs,
parallelRatio: Math.floor(nTotalET / nTotalWorkMs * 1000) / 1000
}
}
catch (error) {
console.log(error)
}
};
Response:
{
"jobsCount": 3000,
"spawnCompletionMs": 1879,
"spawnCompletionPct": "2.91%",
"totalElapsedMs": 64546,
"totalWorkMs": 3004205,
"parallelRatio": 0.021
}
Request ID:
"43f31584-238e-4af9-9c5d-95ccab22ae84"
我是否达到了我没有提到的其他限制?我的测试代码有缺陷吗?我试图在这里达到 3,000 名工作人员的限制,但没有遇到任何限制,我猜这是由于异步调用重试行为。
编辑:任一 Lambda 均不涉及 VPC;选择输入中的设置是“No VPC”。
编辑:在修复前后显示 Cloudwatch
【问题讨论】:
-
您的 AWS Lambda 函数的配置是什么?是否在 VPC 中?
-
“我猜这是由于异步调用重试行为造成的。” 您正在使用
InvocationType: "RequestResponse"- 这意味着同步,而不是异步,即使您的处理程序是async函数。服务不会重试。但是,如果您也将调用程序作为 lambda 函数运行,那么除非该调用程序函数的容器有很多可用的 CPU 周期(您可以通过增加内存来获得),否则它可能没有资源来生成,签名,并提交足够的同时请求以正确执行测试。也许在 EC2 中运行它。 -
@Michael-sqlbot ROFL!从那个LOL中恢复需要一点时间。所以,实际上,这很方便,不是吗!知道 us-east-2 在初始爆发时只会给您 500,因此可以将其设置为 495 并且永远不要担心会达到 AWS 的油门! Node 的缓存超出了 maxSockets,这(可能)会导致大负载的内存问题,所以有一个小问题,但这可能是次要的。正如我的测试所示,1024MB 以上的性能提升可以忽略不计。好的,现在重新编写这个测试.....
-
@Michael-sqlbot - 你的 Homer Simpson 链接让我现在在做Tim Allen power tool noises!查看更新的屏幕截图。修改后的代码将parallelRatio从0.022粉碎到0.008!这很有趣!!如果你在回答表格中写了一个,我可以让你检查。 我经常在俄勒冈州立大学看望我的孩子,但并没有完全了解“谁戴”县。下次我欠你一些啤酒!谢谢。
标签: node.js amazon-web-services aws-lambda