如何在AWS Lambda上部署phantomjs节点应用程序?

时间:2016-08-07 15:47:29

标签: node.js phantomjs casperjs aws-lambda spookyjs

我将一个小型Lambda函数拼凑在一起,使用SpookyJS,CasperJS和PhantomJS工具链抓取网站进行无头浏览。任务很简单,几个月前它在Lambda工作。我最近不得不改变一些事情,并希望再次参与该项目,但是开始新鲜并且无法在没有任何错误的情况下运行Lambda。我的问题是如何在Lambda中运行phantomjs

我正在运行的示例代码是:

spooky.start('http://en.wikipedia.org/wiki/Spooky_the_Tuff_Little_Ghost');
spooky.then(function () {
    this.emit('hello', 'Hello, from ' + this.evaluate(function () {
        return document.title;
    }));
});
spooky.run();

我在Lambda中遇到的错误是:

{ [Error: Child terminated with non-zero exit code 1] details: { code: 1, signal: null } }

我已经遵循了各种程序来确保一切都能够在Lambda上运行。以下是我尝试诊断的一长串事项:

  1. 使用node index.js在本地运行并确认其正常运行
  2. 将package.json和js文件上传到Amazon Linux EC2实例,以便按照npm安装调用的建议进行编译,并描述here
  3. 在ec2实例上运行npm install,然后再次运行node index.js以确保输出正确
  4. 将所有内容压缩,然后使用cli
  5. 部署到AWS

    我的package.json是:

    {
      "name": "lambda-spooky-test",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "",
      "license": "ISC",
      "dependencies": {
        "casperjs": "^1.1.3",
        "phantomjs-prebuilt": "^2.1.10",
        "spooky": "^0.2.5"
      }
    }
    

    我还尝试了以下方法(大多数也在本地工作,在AWS EC2实例上工作,但在Lambda上有相同的错误:

    1. 试用幻像的非预建版本
    2. 使用process.env['PATH'] = process.env['PATH'] + ':' + process.env['LAMBDA_TASK_ROOT'] + ':' + process.env['LAMBDA_TASK_ROOT'] + '/node_modules/.bin'; console.log( 'PATH: ' + process.env.PATH );
    3. 确保可以从路径访问casperjs和phantomjs
    4. 通过包装child_process的.spawn()调用来检查生成调用,并获得以下内容:

      { '0': 'casperjs',
        '1': 
         [ '/var/task/node_modules/spooky/lib/bootstrap.js',
           '--transport=http',
           '--command=casperjs',
           '--port=8081',
           '--spooky_lib=/var/task/node_modules/spooky/lib/../',
           '--spawnOptions=[object Object]' ],
        '2': {} }
      
    5. 直接调用.exec('casperjs').exec('phantomjs --version'),确认它在本地和EC2上有效,但在Lambda中收到以下错误。命令:

      `require('child_process').exec('casperjs', (error, stdout, stderr) => {
      if (error) { console.error('error: ' + error); }
         console.log('out: ' + stdout);
         console.log('err: ' + stderr);
      });
      
    6. 两者,结果如下:

      err: Error: Command failed: /bin/sh -c casperjs
      module.js:327
          throw err;
          ^
      
      Error: Cannot find module '/var/task/node_modules/lib/phantomjs'
          at Function.Module._resolveFilename (module.js:325:15)
          at Function.Module._load (module.js:276:25)
          at Module.require (module.js:353:17)
          at require (internal/module.js:12:17)
          at Object.<anonymous> (/var/task/node_modules/.bin/phantomjs:16:15)
          at Module._compile (module.js:409:26)
          at Object.Module._extensions..js (module.js:416:10)
          at Module.load (module.js:343:32)
          at Function.Module._load (module.js:300:12)
          at Function.Module.runMain (module.js:441:10)
      
      2016-08-07T15:36:37.349Z    b9a1b509-5cb4-11e6-ae82-256a0a2817b9    sout: 
      2016-08-07T15:36:37.349Z    b9a1b509-5cb4-11e6-ae82-256a0a2817b9    serr: module.js:327
          throw err;
          ^
      
      Error: Cannot find module '/var/task/node_modules/lib/phantomjs'
          at Function.Module._resolveFilename (module.js:325:15)
          at Function.Module._load (module.js:276:25)
          at Module.require (module.js:353:17)
          at require (internal/module.js:12:17)
          at Object.<anonymous> (/var/task/node_modules/.bin/phantomjs:16:15)
          at Module._compile (module.js:409:26)
          at Object.Module._extensions..js (module.js:416:10)
          at Module.load (module.js:343:32)
          at Function.Module._load (module.js:300:12)
          at Function.Module.runMain (module.js:441:10)
      

1 个答案:

答案 0 :(得分:3)

我发现问题包括路径中的node_modules/.bin在本地和ec2机器上都有效,因为这些文件只指向每个相应库中的动作/bin文件夹。如果这些文件中的调用使用相对路径,则会中断。问题:

[ec2-user@ip-172-31-32-87 .bin]$ ls -lrt
total 0
lrwxrwxrwx 1 ec2-user ec2-user 35 Aug  7 00:52 phantomjs -> ../phantomjs-prebuilt/bin/phantomjs
lrwxrwxrwx 1 ec2-user ec2-user 24 Aug  7 00:52 casperjs -> ../casperjs/bin/casperjs

我通过将每个库的相应bin添加到Lambda处理函数中的lambda路径来解决这个问题:

process.env['PATH'] = process.env['PATH'] + ':' + process.env['LAMBDA_TASK_ROOT'] 
        + ':' + process.env['LAMBDA_TASK_ROOT'] + '/node_modules/phantomjs-prebuilt/bin'
        + ':' + process.env['LAMBDA_TASK_ROOT'] + '/node_modules/casperjs/bin';

现在,这将在Lambda中正确地运行幻像,casper和spooky。