node 事件监听超出10个以上怎么处理?
发布于 10小时前 作者 xchl 161 次浏览 来自 问答

代码抄自《深入浅出nodejs》

    var EventEmitter = require('events').EventEmitter;
    var event = new EventEmitter();
    var fs = require('fs');
    var status = 'ready';
    var readFile = function(callback){
        event.once('read',callback)
        if(status == 'ready'){
            status = 'reading';
            fs.readFile('a.json','utf-8',function(){
                event.emit('read',res);
                status = 'ready';
            })
        }
    }
    //下面会出警告监听器超出10有内存溢出的危险。
    for (var i = 0; i < 11; i++){   
        readFile(function(res){
            console.log(res)
        });
    }

监听器超过10个node就会出警告有内存溢出的危险,想知道这种情况除了setMaxListenters()还有其他解决方案吗。或者其他思路实现上例中的方法。

8 回复

按照楼主给出了代码测试了下,的确报错,但其实错误是说明event监听read事件方法的个数超出了最大数量。 按照你给出的代码是想顺序读取同一个文件的吧,但这在node是不可能的。

@joney-pinkman 这里想实现的效果这样的,for循环那里是模仿同时11次请求。比如同时11条请求都是读取同一个文件,给11条请求都加上监听。然后只读一次文件,而不用读11次。

放心吧,一般情况下不会超过10个的。你可以假设下即使是做消息转发等业务,也仅仅是定义一个消息协议,监听一个,至于不同的消息类型是内部控制的,再加上node本身不适合做大型的server端,所以不必担心。当然,或许你的场景有这样的需求,不妨一起讨论下。

@xchl 你的这个思路有点不大对,对于读取文件或者请求数据等操作,一般情况下都是很快的,你可以理解为请求完后能够立即拿到回执,所以并行的的11次和串行的11次没多大关系,其次对于频繁访问的数据一般操作都是建立缓存,可以使用redis、memcache等,利用其高效的访问速度进行处理。

@haozxuan 恩 我也觉的有点纠结,这个思路在请求并发的时候不会对数据库,或者是io上造成太大的压力,但会有内存泄露的危险。下面是这个思路完整的代码。觉的作者这个思路很好,就是不知道怎么规避事件监听的问题

./ab -n11 -c11 http://127.0.0.1:1337/

var http = require('http');
var EventEmitter = require('events').EventEmitter;
var event = new EventEmitter();
var fs = require('fs');
var status = 'ready';
var readFile = function(callback){
    event.once('read',callback);
    if(status === 'ready'){
        console.log('这里只会读取一次文件');
        status = 'pending';
        fs.readFile('a.json','utf-8',function(err,res){
            event.emit('read',res);
            status = 'ready';
        });
    }
}
http.createServer(function(req,res){
    res.writeHead(200, {'Content-Type': 'text/plain'});
    readFile(function(res){
        console.log(res);
    })
    res.end('res');
}).listen(1337,'127.0.0.1');

@xchl 你的需求并不明确,贴出来的这部分代码的确是一个经典的demo,但并不能作为一个可用的server端,因为每次http请求的目的是获取a.json的内容,那么完全不必要注册事件,可以直接去读取文件。

@haozxuan 这里绑定事件的想法是这样的, 同样的并发数下测试 ./ab -n11 -c11 http://127.0.0.1:1337,如果直接读取的话会读11次这个文件,按照上面的思路只会读1次,相比直接读少了10次。

cluster 模式下怎么保证呢?

回到顶部