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后,现在又开始报错。


2 回复

Nodejs emitter.setMaxListeners()的问题

在高并发场景下,你可能会遇到EventEmitter对象的监听器数量超过默认限制的情况。默认情况下,每个EventEmitter对象最多允许添加10个监听器。如果超过这个数量,Node.js会发出警告,并且可能影响性能。

问题描述

你在使用exBuffer对socket接收到的数据进行分包处理时遇到了问题。具体来说,在高并发场景下,你发现EventEmitter对象的监听器数量超过了默认的最大值(最初为10),即使你已经将其调整为30,仍然出现了错误提示。

错误信息

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

解决方案

你可以通过调用emitter.setMaxListeners(n)方法来增加EventEmitter对象的最大监听器数量。这可以有效地解决由于监听器数量过多导致的内存泄漏警告。

示例代码

假设你的代码结构如下:

const net = require('net');
const exBuffer = require('./ExBuffer');

const socketCli = net.createConnection({ port: 8080, host: 'localhost' }, () => {
  console.log('Connected to server!');
});

exBuffer.on('data', function(data) {
  // 处理接收到的数据
  console.log('Data received:', data);
});

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

// 设置最大监听器数量
exBuffer.setMaxListeners(50); // 根据需要调整这个值
socketCli.setMaxListeners(50); // 同样也可以设置socket的监听器数量

解释

  1. setMaxListeners:这个方法用于设置EventEmitter对象的最大监听器数量。你可以根据实际需求调整这个值,以避免因监听器过多而导致的警告。

  2. 设置监听器数量:在示例中,我们将exBuffersocketCli的监听器数量都设置为了50。你可以根据实际情况调整这个值,以确保不会因为监听器数量过多而引发警告。

通过这种方式,你可以有效地解决EventEmitter对象的监听器数量过多的问题,并且避免因监听器数量过多而导致的内存泄漏警告。


从你的描述来看,这个问题是由于EventEmitter的默认最大监听器限制被突破导致的。当一个EventEmitter对象上添加了超过默认的最大监听器数(默认为10)的监听器时,Node.js会发出警告,并且如果你继续添加监听器,最终可能会导致内存泄漏。

你可以通过调用emitter.setMaxListeners(n)方法来增加最大监听器的数量。然而,仅仅增加这个数值可能并不是解决问题的最佳方式,因为这可能是潜在设计问题的一个症状。

示例代码

假设你想将默认的最大监听器数增加到30:

const EventEmitter = require('events');

// 假设这是你的exBuffer类
class ExBuffer extends EventEmitter {
    // 构造函数和其他方法...
}

const exBuffer = new ExBuffer();

// 设置最大监听器数量
exBuffer.setMaxListeners(30);

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

const socketCli = /* 假设这是你的socket对象 */;
socketCli.on('data', function(data) {
    exBuffer.put(data);
});

解释

  • exBuffer.setMaxListeners(30); 这行代码将exBuffer的最大监听器数设置为30。这意味着它现在可以处理多达30个的'data'事件监听器。

  • 然而,你应该更深入地考虑为什么需要这么多监听器。通常情况下,一个事件应该只触发少数监听器。如果确实有很多监听器被注册,那么可能需要重新评估你的设计,看看是否可以减少不必要的监听器或者优化你的事件处理逻辑。

如果你的应用中真的需要大量的监听器,那么你可以根据需要调整setMaxListeners的值。但请注意,这只是掩盖问题的一种方法,而不是根本的解决方案。

回到顶部