首页 > nodejs爬网页的时候报错:(libuv) kqueue(): Too many open files in system

nodejs爬网页的时候报错:(libuv) kqueue(): Too many open files in system

主要代码:

db_operation.db_getUrl('appsIndex_China', function(results){
    var arr = [],
        length = results.length;
    for(var i = 0; i < length; i++)
    {
        var item = results[i];
        (function(i, item){
            request(item.url, function(error, response, body){
                if(!error && response.statusCode == 200)
                {
                    $ = cheerio.load(body);
                    getAppDetail('#content', function(data){
                        data.id = item.id;
                        arr.push(data);
                        
                    });
                    if(arr.length == 100)
                    {
                        db_operation.db_addBasciDetail('appBasicDetail_China', arr);
                    }
                }    
            })
        }(i, item));
    }
})

length大概是1w6,应该是request的地址太多了,求问该怎么解决?跪谢!

baidu+google了一下,说要改系统最大打开的文件数,但是我现在能打开的文件数已经是1000000了:


1)OS能同时打开的文件数量有限制,即使你调大的系统值,也是有一个瓶颈的
2)你要在代码中控制发送的异步请求的数量控制一定范围内,发送的过多实际上也没有意义,服务器发现同一个IP过来的请求数过多,也会拒绝你的请求

你可以做如下修改试试:

//全部请求完成后的回调函数
function appsIndexChinaProcessDone(){
    
}

db_operation.db_getUrl('appsIndex_China', function(results){
    var arr = [],
        length = results.length;
    
    var correntRequest=1000;
    var finishedRequest=0;
    function processNext(){
        var item=results.shift();
        if(someData){
            request(item.url, function(error, response, body){
                if(!error && response.statusCode == 200)
                {
                    $ = cheerio.load(body);
                    getAppDetail('#content', function(data){
                        data.id = item.id;
                        arr.push(data);

                    });
                    if(arr.length == 100)
                    {
                        finishedRequest++;
                        db_operation.db_addBasciDetail('appBasicDetail_China', arr);
                    }
                    //也可以加在此时,只要回来200,不管有没有取到需要的数据
                    //finishedRequest++;
                }else{
                    //放回队列中等待下次再尝试执行
                    //也可以不处理,看你的业务需求
                    results.push(item);
                }
                //获取下一个数据,发送请求
                processNext();
            })
        }else{
            //因为异步请求,队列为空,不等于所有的请求处理完毕,需要判断时候完成的请求数量和实际要求的数量是否吻合
            if(finishedRequest===length){
                console.log('process done!');
                //全部执行完后执行回调,通知数据抓取完成
                appsIndexChinaProcessDone();
            }
        }
        
    }
    
    //设置并发的初始请求数量,后续的请求通过processNext依次执行,一直到队列为空
    for(var i=0;i<correntRequest;i++){
        processNext();
    }
});
【热门文章】
【热门文章】