AWS Lambda 上的 PhantomJS 总是超时
Posted
技术标签:
【中文标题】AWS Lambda 上的 PhantomJS 总是超时【英文标题】:PhantomJS on AWS Lambda Always Timeout 【发布时间】:2017-07-20 11:24:24 【问题描述】:我正在尝试在 AWS Lambda 上创建一个任务,从 PhantomJS 创建 PDF 文件,然后稍后将其上传到 AWS S3。
现在,我尝试在 Lambda 上运行它,但它总是超时。
我的 Lambda 有 128mb 的内存。运行时是 node.js 4.4.3。
这是我从 Lambda 得到的错误
"errorMessage": "2017-03-01T08:05:56.255Z dfd4cfe8-fe55-11e6-bf24-e7edf412e037 Task timed out after 10.00 seconds"
这些也是日志输出
REPORT RequestId: dfd4cfe8-fe55-11e6-bf24-e7edf412e037 Duration: 10000.08 ms Billed Duration: 10000 ms Memory Size: 128 MB Max Memory Used: 29 MB
2017-03-01T08:05:56.255Z dfd4cfe8-fe55-11e6-bf24-e7edf412e037 Task timed out after 10.00 seconds
这是我的代码。
Index.js
var childProcess = require('child_process');
var path = require('path');
exports.handler = function(event, context, callback)
// Set the path as described here: https://aws.amazon.com/blogs/compute/running-executables-in-aws-lambda/
process.env['PATH'] = process.env['PATH'] + ':' + process.env['LAMBDA_TASK_ROOT'];
// Set the path to the phantomjs binary
var phantomPath = path.join(__dirname, 'phantomjs_linux-x86_64');
// Arguments for the phantom script
var processArgs = [
path.join(__dirname, 'phantom-script.js'),
event.url
];
// Launc the child process
childProcess.execFile(phantomPath, processArgs, function(error, stdout, stderr)
if (error)
context.fail(error);
return;
if (stderr)
context.fail(error);
return;
context.succeed(stdout);
);
phantom-script.js
var system = require('system');
var args = system.args;
// Example of how to get arguments passed from node script
// args[0] would be this file's name: phantom-script.js
const url = "https://google.com";
system.stdout.write('hello from phantom!');
console.log("task start, target url = " + url);
console.time("execute time");
phantom.create().then(function(ph)
console.time("create Page");
ph.createPage().then(function(page)
console.timeEnd("create Page");
console.time("open website");
page.open(url).then(function(status)
console.timeEnd("open website");
console.time("render as pdf");
page.render('google.pdf').then(function()
console.timeEnd("render as pdf");
console.log('Page Rendered');
ph.exit();
// send to s3
console.timeEnd("execute time");
);
);
);
);
// Send some info node's childProcess' stdout
system.stdout.write('hello from phantom!')
phantom.exit();
我尝试按照answer 做我的工作,但它不起作用。
我没有从我的phantom-script.js
获得任何日志,就像它不是触发器一样,但我的任务总是超时。
【问题讨论】:
我处于类似情况,将页面渲染为图像,并且在尝试 page.render 后似乎超时。相同的记忆,30秒。你有什么发现吗? 实际上,只是尝试在我的代码的不同部分使用 context.getRemainingTimeinMillis() ,看看我是否真的“适当地”超时了。很长一段时间后,我意识到我只是用 phantomjs 达到了最大内存,所以我翻了一番,达到 256mb。 @svjacob 我在下面的答案中添加了适合我的解决方案。这对我来说是工作。希望对您有所帮助。 【参考方案1】:在我花了很多时间之后。我找到了包名Phantomjs-Prebuilt,您可以通过npm
安装它。您必须在具有节点版本 4.x(lambda 使用节点版本 4.3)的 amazon linux 实例或 docker amazon linux 上执行 npm install
。否则它将无法在 lambda 上运行。
然后,我像这样更新了我的代码。
Index.js
var phantomjs = require('phantomjs-prebuilt')
exports.handler = function(event, context, callback)
var sourceUrl = "https://example.com"
var program = phantomjs.exec('phantom-script.js', sourceUrl)
program.stdout.pipe(process.stdout)
program.stderr.pipe(process.stderr)
program.on('exit', code =>
// do something here after you phantomjs finish.
return
)
phantom-script.js
var system = require('system')
var args = system.args
// Example of how to get arguments passed from node script
// args[0] would be this file's name: phantom-script.js
var url = args[1] // received sourceUrl value
// Send some info node's childProcess' stdout
system.stdout.write('phantomJS running\r\n')
var webpage = require('webpage').create()
webpage.paperSize =
format: 'A4',
orientation: 'landscape'
webpage.open(url, function(status)
system.stdout.write('start open page\r\n')
webpage.render('/tmp/web.pdf',
format: 'pdf',
quality: '100'
)
system.stdout.write('finish render page\r\n')
phantom.exit()
)
在 lambda 上,您可以写入文件的位置是 /tmp
文件夹,这就是我将文件保存在那里的原因。
我通过 lambda 运行它,内存为 192mb。它的工作真的很好。我可以使用此设置创建包含 500 张图像的网页截图。最重要的是确保您的 lambda 能够连接互联网。
仅供参考,我意识到当 phantom-script.js(我在其中编写幻像脚本的文件)出现错误时,您的 lambda 将冻结直到超时。这就是为什么我总是收到来自 lambda Task timed out after 10.00 seconds
的回复。
【讨论】:
以上是关于AWS Lambda 上的 PhantomJS 总是超时的主要内容,如果未能解决你的问题,请参考以下文章
aws lambda 上的保留并发不会阻止 lambda 进行更多扩展?
schedult 上的 aws 自定义事件以触发 lambda 使用 Terraform
是啥导致 AWS Lambda 上的 Mongodb 超时错误?