开发者社区> 问答> 正文

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了

展开
收起
我的中国 2016-02-08 19:52:17 4222 0
1 条回答
写回答
取消 提交回答
  • R&amp;S网络资深工程师 ,阿里云论坛官方版主,阿里云云计算ACP,春考教学网站长,IT技术晋级之路专辑作者
    采纳回答

    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();
    }

    });

    2019-07-17 18:28:21
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
探究 Node.js 的服务端之路 立即下载
个推微服务实践 基于OpenResty 和Node.js 立即下载
沪江基于Node.js大规模应用实践 立即下载