Nodejs emitter.setMaxListeners()的问题

Nodejs emitter.setMaxListeners()的问题

我使用exBuffer进行的socket数据分包

var exBuffer = new ExBuffer();
exBuffer.on('data', function(data){
	// do code
})
socketCli.on('data', function(data) {
   exBuffer.put(data);
});

在大并发量下,现在会报错

(node) warning: possible EventEmitter memory leak detected. 31 listeners added. Use emitter.setMaxListeners() to increase limit.
Trace
    at Socket.EventEmitter.addListener (events.js:175:15)
    at client.connection (/data/node/online/client.js:57:23)
    at EventEmitter.emit (events.js:96:17)
    at proc (/data/node/node_modules/ExBuffer/ExBuffer.js:151:26)
    at put (/data/node/node_modules/ExBuffer/ExBuffer.js:100:9)
    at Socket.client.connection (/data/node/client.js:96:22)
    at Socket.EventEmitter.emit (events.js:96:17)
    at TCP.onread (net.js:396:14)

使用的nodejs的NET建立socket,socket监听到的消息全部交给exBuffer处理进行分包,解决之前出现的粘包问题。

但是现在会报错,提示监听数量达到了最大值,最开始提示10,我设置为30后,现在又开始报错。


4 回复

Nodejs emitter.setMaxListeners()的问题

在高并发场景下,你可能会遇到EventEmitter内存泄漏警告。这通常是由于添加了过多的事件监听器导致的。例如,在你的代码中,exBuffersocketCli 都注册了大量的事件监听器,这可能导致EventEmitter内存泄漏警告。

示例代码及问题描述

var exBuffer = new ExBuffer();
exBuffer.on('data', function(data){
	// 处理数据
});

socketCli.on('data', function(data) {
   exBuffer.put(data);
});

当你运行上述代码时,在高并发情况下可能会看到类似以下的错误信息:

(node) warning: possible EventEmitter memory leak detected. 31 listeners added. Use emitter.setMaxListeners() to increase limit.

解决方案

为了防止这种内存泄漏警告,你可以通过调用emitter.setMaxListeners()方法来增加EventEmitter可以处理的最大监听器数量。默认情况下,每个EventEmitter对象的监听器数量限制为10个。

示例代码
var events = require('events');
var util = require('util');

function ExBuffer() {
	events.EventEmitter.call(this);
}
util.inherits(ExBuffer, events.EventEmitter);

ExBuffer.prototype.setMaxListeners(50); // 设置最大监听器数量为50

var exBuffer = new ExBuffer();
exBuffer.on('data', function(data){
	// 处理数据
});

socketCli.on('data', function(data) {
   exBuffer.put(data);
});

// 如果需要,也可以直接修改全局EventEmitter的最大监听器数量
events.EventEmitter.defaultMaxListeners = 50;

在这个示例中,我们首先定义了一个继承自EventEmitterExBuffer类,并在构造函数中调用了events.EventEmitter.call(this)来初始化父类。然后我们通过setMaxListeners(50)方法将ExBuffer实例的最大监听器数量设置为50。

此外,你还可以直接修改全局的EventEmitter的最大监听器数量,如上所示,通过events.EventEmitter.defaultMaxListeners = 50;来实现。

总结

通过合理地调整emitter.setMaxListeners()的值,可以有效地避免在高并发场景下的EventEmitter内存泄漏警告。但需要注意的是,设置过高的监听器数量可能会消耗更多的内存资源,因此应根据实际应用场景谨慎调整。


不是我干的啊,怎么会提交了这么多…

/data/node/online/client.js 57行附近的代码贴出来 从warning信息来看,是对同一个socket无节制通过on注册监听函数,却没有适当注销。

在Node.js中,EventEmitter 类默认的最大监听器数量是10个。当超过这个数量时,Node.js会发出警告,提示可能存在内存泄漏。你可以通过调用 emitter.setMaxListeners(n) 方法来增加这个限制。

根据你的描述,在大并发量下,你遇到的错误是由于超过了默认的最大监听器数量(10)导致的。你将最大监听器数量增加到了30,但仍然遇到了问题。你需要进一步调整这个值或者优化代码逻辑。

示例代码

const EventEmitter = require('events');
const exBuffer = new EventEmitter();

// 增加最大监听器数量到100
exBuffer.setMaxListeners(100);

exBuffer.on('data', function(data) {
    // 处理数据
});

// 假设这是你的socket连接代码
const socketCli = require('net').createServer();
socketCli.on('connection', (socket) => {
    socket.on('data', function(data) {
        exBuffer.emit('data', data);  // 将数据传递给exBuffer
    });
});

socketCli.listen(3000, () => {
    console.log('Server listening on port 3000');
});

解释

  • setMaxListeners(n): 这个方法可以用来增加特定 EventEmitter 实例的最大监听器数量。
  • 在上面的代码中,我们把 exBuffer 的最大监听器数量设置为了100,这应该能够应对更大的并发量。
  • 使用 emit 方法可以手动触发事件,这里我们将接收到的数据传递给 exBuffer

如果设置为更大的值后仍然出现问题,可能需要考虑是否有必要为每个连接都添加一个监听器,或者是否有更高效的处理方式来减少不必要的监听器。

回到顶部