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后,现在又开始报错。
Nodejs emitter.setMaxListeners()的问题
在高并发场景下,你可能会遇到EventEmitter内存泄漏警告。这通常是由于添加了过多的事件监听器导致的。例如,在你的代码中,exBuffer
和 socketCli
都注册了大量的事件监听器,这可能导致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;
在这个示例中,我们首先定义了一个继承自EventEmitter
的ExBuffer
类,并在构造函数中调用了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
。
如果设置为更大的值后仍然出现问题,可能需要考虑是否有必要为每个连接都添加一个监听器,或者是否有更高效的处理方式来减少不必要的监听器。