Node.js 内存泄漏
NodeJS memory leak
我正在使用 socket.io
和 mysql
制作游戏,并且在每个客户端连接时,我都会使用 我的自定义 [=33] 检查用户是否被 IP 禁止=]函数:
MySQL.Query('SELECT * FROM bans WHERE user = ?', username, function(rows) {
// do something
})
但当我连接 > 5 个客户端时,我在服务器控制台上出现此错误:
(node) warning: possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit.
Trace
at PoolConnection.addListener (events.js:239:17)
at C:\Users\user\Documents\_server\mysql\mysql.js:26:21
at Ping.onOperationComplete [as _callback] (C:\Users\user\node_modules\mysql\lib\Pool.js:99:5)
at Ping.Sequence.end (C:\Users\user\node_modules\mysql\lib\protocol\sequences\Sequence.js:96:24)
at Ping.Sequence.OkPacket (C:\Users\user\node_modules\mysql\lib\protocol\sequences\Sequence.js:105:8)
at Protocol._parsePacket (C:\Users\user\node_modules\mysql\lib\protocol\Protocol.js:280:23)
at Parser.write (C:\Users\user\node_modules\mysql\lib\protocol\Parser.js:73:12)
at Protocol.write (C:\Users\user\node_modules\mysql\lib\protocol\Protocol.js:39:16)
at Socket.<anonymous> (C:\Users\user\node_modules\mysql\lib\Connection.js:96:28)
at emitOne (events.js:77:13)
这是 mysql.js 文件 :
var config = require('../config.js');
var mysql = require('mysql');
var pool = mysql.createPool({
connectionLimit : 100,
host : config.sqlhost,
user : config.sqluser,
password : config.sqlpass,
database : config.sqlbase,
debug : false
});
var MySQL = {
Query: function(req, reqvars, callback) {
pool.getConnection(function(err,connection){
if (err) {
connection.release();
console.log('[MySQL] Error while connecting to the database');
}
connection.query(req, reqvars, function(err,rows){
connection.release();
if (typeof callback == 'function') callback(rows);
});
connection.on('error', function(err) {
console.log('[MySQL] Error while attempting query');
});
});
},
}
module.exports = MySQL;
问题出在哪里?
Node.js 每当您在单个事件发射器上为同一事件附加 10 个以上(默认)侦听器时都会发出警告。
在您的特定情况下,每次进行 SQL 查询时,您都会将 error
侦听器附加到 connection
对象。这可能不是您想要的,因为如果前 x 个查询执行得很好,但随后有一个失败,那么前一个查询的那些 error
处理程序仍将被调用。
补救措施
虽然我没有使用 mysql 库的实际经验,但让我震惊的第一件事是您完全忽略了 connection.query()
回调的 err
参数。您绝不能忽略这些,除非您想花费数小时来调试一段看似有效的代码。
您似乎不需要将 error
处理程序附加到 connection
,您只需检查 err
参数即可。
PS. It is common practice to always pass along any errors that occur during execution as the first argument in callback-based APIs (specifying null
in case of no error). Your callback
function seems to not adhere to this practice.
我正在使用 socket.io
和 mysql
制作游戏,并且在每个客户端连接时,我都会使用 我的自定义 [=33] 检查用户是否被 IP 禁止=]函数:
MySQL.Query('SELECT * FROM bans WHERE user = ?', username, function(rows) {
// do something
})
但当我连接 > 5 个客户端时,我在服务器控制台上出现此错误:
(node) warning: possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit.
Trace
at PoolConnection.addListener (events.js:239:17)
at C:\Users\user\Documents\_server\mysql\mysql.js:26:21
at Ping.onOperationComplete [as _callback] (C:\Users\user\node_modules\mysql\lib\Pool.js:99:5)
at Ping.Sequence.end (C:\Users\user\node_modules\mysql\lib\protocol\sequences\Sequence.js:96:24)
at Ping.Sequence.OkPacket (C:\Users\user\node_modules\mysql\lib\protocol\sequences\Sequence.js:105:8)
at Protocol._parsePacket (C:\Users\user\node_modules\mysql\lib\protocol\Protocol.js:280:23)
at Parser.write (C:\Users\user\node_modules\mysql\lib\protocol\Parser.js:73:12)
at Protocol.write (C:\Users\user\node_modules\mysql\lib\protocol\Protocol.js:39:16)
at Socket.<anonymous> (C:\Users\user\node_modules\mysql\lib\Connection.js:96:28)
at emitOne (events.js:77:13)
这是 mysql.js 文件 :
var config = require('../config.js');
var mysql = require('mysql');
var pool = mysql.createPool({
connectionLimit : 100,
host : config.sqlhost,
user : config.sqluser,
password : config.sqlpass,
database : config.sqlbase,
debug : false
});
var MySQL = {
Query: function(req, reqvars, callback) {
pool.getConnection(function(err,connection){
if (err) {
connection.release();
console.log('[MySQL] Error while connecting to the database');
}
connection.query(req, reqvars, function(err,rows){
connection.release();
if (typeof callback == 'function') callback(rows);
});
connection.on('error', function(err) {
console.log('[MySQL] Error while attempting query');
});
});
},
}
module.exports = MySQL;
问题出在哪里?
Node.js 每当您在单个事件发射器上为同一事件附加 10 个以上(默认)侦听器时都会发出警告。
在您的特定情况下,每次进行 SQL 查询时,您都会将 error
侦听器附加到 connection
对象。这可能不是您想要的,因为如果前 x 个查询执行得很好,但随后有一个失败,那么前一个查询的那些 error
处理程序仍将被调用。
补救措施
虽然我没有使用 mysql 库的实际经验,但让我震惊的第一件事是您完全忽略了 connection.query()
回调的 err
参数。您绝不能忽略这些,除非您想花费数小时来调试一段看似有效的代码。
您似乎不需要将 error
处理程序附加到 connection
,您只需检查 err
参数即可。
PS. It is common practice to always pass along any errors that occur during execution as the first argument in callback-based APIs (specifying
null
in case of no error). Yourcallback
function seems to not adhere to this practice.