AWS Lambda上的PhantomJS总是超时

5
我正在尝试在AWS Lambda上创建一个任务,该任务使用PhantomJS创建PDF文件,然后稍后将其上传到AWS S3。
现在,我尝试在Lambda上运行它,但总是超时。
我的Lambda有128MB的RAM。运行时为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();

我尝试按照这个答案来完成我的工作,但是它没有起作用。

我从我的phantom-script.js中没有得到任何日志,就像它没有触发一样,但我的任务总是超时。


我处于类似的情况,将页面渲染为图像,在尝试page.render后似乎会超时。相同的内存,30秒。你有什么想法吗? - sjacob
实际上,我刚刚尝试在代码的不同部分使用context.getRemainingTimeinMillis(),以查看是否真正“适当”超时。经过很长时间,我意识到我只是用phantomjs达到了最大内存限制,所以我将其加倍到256mb。 - sjacob
1
@svjacob 我在下面的答案中添加了对我有效的解决方案。这对我有用。希望能帮到你。 - Natsathorn
1个回答

3
在我花费了很多时间之后,我找到了包名为Phantomjs-Prebuilt的包,您可以通过npm安装它。您必须在Amazon Linux实例或Docker Amazon Linux上执行npm install,该实例必须拥有Node版本4.x(Lambda使用的是Node版本4.3)。否则,它将无法在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文件夹,所以我将文件保存在那里。
我通过只使用192mb的ram在lambda上运行它。它工作得非常好。我可以使用这个设置创建一个包含500张图片的网页截图。最重要的是确保您的lambda能够连接到互联网。
顺便说一下,我发现当phantom-script.js(我用于写幻象脚本的文件)出现错误时,您的lambda会冻结直到超时。这就是为什么我总是从lambda获取此响应Task timed out after 10.00 seconds

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接