代码之家  ›  专栏  ›  技术社区  ›  dsp_099

当从启动时计划的永远脚本调用节点的spawn()时,它会自动失败

  •  5
  • dsp_099  · 技术社区  · 10 年前

    这有点愚蠢。这个问题很可能与服务器有关,因此我的第一个求助是 AskUbuntu over here .

    我在试着用crontab或rc。本地或初始化。d启动 forever 启动时脚本。它将一台服务器连接到一个端口上,我可以ping一些信息,并让它为我运行一个无头浏览器。

    也就是说,我似乎无法从Node.js得到响应 spawn() :

    var CASPER_PATH = '/home/ubuntu/dev/casperjs/bin/casperjs'; // actual binary location, not a symlink
    var SCRIPTS_PATH = '/home/custom_user/endpoints/server.js';
    
    var fileName = req.body.source + '_' + req.body.type + '.coffee'; // looks like: mysource_my_scrape_type.coffee
    var scrapeId = 'test_scrape';
    var user = 'user123';
    var pass = 'pass123';
    if (fs.existsSync(SCRIPTS_PATH + fileName)) {
      // If file is in place, spawn casperjs
      var sP = spawn(CASPER_PATH, 
        [SCRIPTS_PATH + fileName, '--ssl-protocol=any', '--user='+user, '--scrapeId='+scrapeId, '--pass='+pass], 
        { detached: true }, 
        function (err, stdout, stderr) {});
      sP.stdout.on('data', function(data) { console.log('stdout', data.toString('utf8')); });
      sP.stderr.on('data', function(data) { console.log('stderr', data.toString('utf8')); });
      sP.stdout.on('close', function(code) { console.log('close', code); });
      res.send({ scheduled: true, key: scrapeId });
    } else {
      res.send({ scheduled: false, error: 'Incorrect source, type or the script is missing.' });
    }
    

    在我添加 PHANTOMJS_EXECUTABLE env到 crontab 或 rc.local (似乎与用户级别无关),stdout很有用:

    stdout致命:[Errno 2]没有此类文件或目录;你安装了吗 幻影?

    关闭false

    既然有了环境变量,那么在 生成() .

    请注意,如果用户(具有任何特权级别)从bash运行node/forever,Casper就可以正常启动。

    我怎么知道为什么 生成() 正在失败?

    2 回复  |  直到 9 年前
        1
  •  2
  •   Borys Serebrov    10 年前

    这实际上看起来像是永远、spawn和casperjs(可能是phantomjs)之间的组合bug。 我能重现你的问题, here is 我的测试应用程序的完整代码。

    您没有显示完整的代码,所以我猜您有一个express应用程序,并且有一个特殊的URL来运行casperjs脚本。

    我构建了这样一个简单的应用程序,它的行为如下:

    • 只需使用启动应用程序 node script.js ( script.js 是运行casperjs脚本的express应用程序 server.js )-它工作正常,呈现响应并将子进程事件处理程序的输出写入控制台
    • 使用init以root身份启动应用程序。d脚本-不起作用,一旦生成子脚本,就不会触发任何事件处理程序
    • 使用init以root身份启动应用程序。d脚本,将casperjs替换为 echo -同样,不起作用 forever 作为根运行, spawn 和 回响 )
    • 使用init以普通用户(非root用户)身份启动应用程序。d、 用“echo”替换casperjs-它有效,事件处理程序被触发,这里我几乎可以肯定问题已经解决,但…:(
    • 使用init以普通用户(非root用户)身份启动应用程序。d、 放回casperjs-它不再工作,不会触发事件处理程序

    实际的解决方案 pm2 ,我这样做了:

    # install pm2
    sudo npm install -g pm2
    # generate init.d scripts for pm2
    # this command will fail, but hint about the correct format with sudo
    pm2 startup ubuntu
    # do this in the folder with your application
    pm2 start script.js
    # remember your application
    pm2 save
    # also useful
    # sudo service stop/start/restart pm2
    # pm2 stop/start/restart script
    

    现在 pm2 将自动启动系统,并启动您的应用程序。一切正常,子进程事件处理程序被触发。

        2
  •  0
  •   Jaffer    10 年前

    我没有完全理解你的要求。但我对Ubuntu无头服务器也有类似的情况。

    我在这里想做的就是我所做的

    首先,我的crontab怎么样?

    crontab -u USER -e
    
    @reboot exec sudo -u USER /bin/bash /home/USER/SHELL_SCRIPT.sh
    

    看,这里我实际上是在启动一个shell脚本,而不是节点服务器

    现在在这个shell脚本(shell_script.sh)中

        #! /bin/bash
        # SHELL_SCRIPT.sh
        cd /home/USER/
        /home/USER/.npm-packages/bin/forever start -p /home/USER -a -d --watch false --pidFile /home/USER/forever.pid -l /home/USER/forever.log -o /home/USER/forever.out -e /home/USER/forever.err /home/USER/MY_NODE.js
    

    甚至在我的my_NODE里。js我遵循绝对路径,我只是忽略$path,不要使用它。

    在这个节点服务器中,我进行了100次繁殖

    现在,我在两年前就这样做了,所以如果你问我为什么这样做,我无法回答