2014-04-17 35 views
0

我正在运行nodejs,而不是作为web服务器,而是从命令行针对phantom-cluster软件包附带的example.js的相当大的修改版本。服务器是AWS实例中的Ubuntu 13.10。Phantom-Cluster的nodejs刚好停止

我的目标是“ping”超过64000个URL来测试404或500 http错误。如果出现错误,请记录该错误以供日后处理。

这里是我的代码:

(function() { 
var WEBSITES, cluster, enqueueRequests, main, phantomCluster; 
var fs = require('fs'); 
phantomCluster = require("./index"); 

cluster = require("cluster"); 
WEBS = []; 

function loadUrls(callback) 
{ 
    console.log("starting loaded"); 
    var fs = require('fs'); 
    var urls = []; 
    fs.readFile("/home/ubuntu/phantom-cluster/theurls.txt", 'utf8', function (err, data) 
    { 
     if (err) throw err; 
     var myArray = data.split("\n"); 
     for(i=0;i<myArray.length;i++) 
     { 
      urls.push(myArray[i]); 
     } 
     callback(null,urls); 
    }) 
} 

enqueueRequests = function(engine) 
{ 
    fulfilled = 0; 
    loadUrls(function(err,WEBS) 
    { 
     console.log(">>" + WEBS.length + " urls to process"); 
     var enqueuer, i, key, _i, _results; 
     enqueuer = function(request) 
     { 
      var item; 
      item = engine.enqueue(request); 

      item.on("timeout", function() 
      { 
       fs.appendFile("/home/ubuntu/error_log.log", "TIMEOUT: " + request + "\r\n", function (err) {}); 
      }); 

      return item.on("response", function() 
      { 
       fulfilled++; 
       console.log(fulfilled); 
      }); 
     }; 

     _results = []; 
     for (i = i = 0;i < 1; i++) 
     { 
      _results.push((function() 
      { 
       var _results1; 
       _results1 = []; 
       for(x=0;x<WEBS.length;x++) 
       { 
        _results1.push(enqueuer(WEBS[x])); 
       } 
       return _results1; 
      })()); 
     } 
     return _results; 
    }); 
}; 

main = function() 
{ 
    var engine; 
    engine = phantomCluster.createQueued(
    { 
     workers: 20, 
     workerIterations: 1, 
     phantomBasePort: 54321 
    }); 
    if (cluster.isMaster) 
    { 
     enqueueRequests(engine); 
    } 


    engine.on("queueItemReady", function(url) 
    { 
     var _this = this; 
     var retVal; 

     urlArray = url.split("|"); 
     var phantom = this.ph; 
     var curPage = phantom.createPage(function(page) 
     { 
      page.set('settings.loadImages', false); 
      page.set('settings.javascriptEnabled', false); 
      page.set('settings.resourceTimeout', 5000); 
      page.set('settings.userAgent','Mozilla/5.001 (windows; U; NT4.0; en-US; rv:1.0) Gecko/25250101'); 
      page.set('onError', function(msg, trace) 
      { 
       var msgStack = ['ERROR: ' + msg]; 
       if (trace && trace.length) 
       { 
        msgStack.push('TRACE:'); 
        trace.forEach(function(t) 
        { 
         msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function +'")' : '')); 
        }); 
       } 
       console.error(msgStack.join('\n')); 
      }); 
      page.set('onResourceReceived', function(response) 
      { 
       if((response.status == "404") || (response.status == "500")) 
       { 
        myUrl = decodeURI(response.url); 
        if(myUrl == urlArray[0]) 
        { 
         retVal = response.status + "|" + url; 
         fs.appendFile("/home/ubuntu/error_log.log", response.status + "|" + url + "\r\n", function (err) {}); 
         return retVal; 
        } 
       }  
      }); 
      page.open(urlArray[0], function(status) 
      { 
       _this.next(); // _this is a PhantomQueuedClusterClient object 
       return _this.queueItemResponse(status); 
      }); 
     }); 
    }); 
    return engine.start(); 
}; 

main(); 

}).call(this); 

其作为index.js引用的文件是在这里: https://github.com/dailymuse/phantom-cluster/blob/master/index.js ,我还没有修改它。

这很好,并引发了20个工作进程出去,并获得排队的url的初始响应代码。

问题出在这里: 经过960-990个URL的处理后,整个事情就停止了。没有错误代码,没有任何东西。

我试过了所有我能想到的从某种节点超时到某个给定网址的问题,以便将我的头撞向我的桌子。当我为它创建一个测试时,前两个会返回一个错误。第三只让我头痛。

任何人有任何帮助或经验的工作?

编辑我对代码进行了更新,并添加了on.response回调函数,然后调用nextTick方法从队列中移除项目。仍然有同样的问题。

+0

如果您增加或减少工作进程的数量,它会改变什么吗? – fmodos

+0

它似乎没有区别。 – jleger

+0

我不知道'this.ph.createPage'或'this.ph.exit'在内部做了什么,但是看着你的代码,好像你只是在页面被打开的时候发回一个响应给队列'return _this.queueItemResponse (状态)',我认为处理后的项目没有被释放队列,并导致引擎停止 – fmodos

回答

0

如果你想要做的只是检查HTTP状态代码,你不需要一个无头浏览器来做到这一点。节点可以自己使用http.request()或使用承诺如request-promise

除非您需要在渲染您正在爬网的页面时验证某些内容,否则不需要在浏览器中渲染页面,只需对URL进行HTTP调用并反省其状态即可。