简体   繁体   English

NodeJS内存泄漏

[英]NodeJS memory leak

I'm making a game with socket.io and mysql , and at every client connect, I check if the user is banned by IP with my custom MySQL function : 我正在用socket.iomysql进行游戏,并且在每个客户端连接时,我都会使用自定义的MySQL函数检查用户是否被IP禁止:

MySQL.Query('SELECT * FROM bans WHERE user = ?', username, function(rows) {
    // do something
})


but when I connect > 5 clients, I have this error on the server console: 但是当我连接> 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)

Here's mysql.js file : 这是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;

Where's the problem? 哪里出问题了?

Node.js warns you whenever you attach more than 10 (the default) listeners for the same event on a single event emitter. 每当在单个事件发射器上为同一事件附加10个以上(默认)侦听器时,Node.js就会警告您。

In your particular case, you attach an error listener to the connection object each and every time you make an SQL query. 在您的特定情况下,每次执行SQL查询时,都将error侦听器附加到connection对象。 This is probably not what you want, because if the first x queries executed fine, but then one fails, those error handlers for the previous queries will still get called. 这可能不是您想要的,因为如果前x个查询执行良好,但随后失败,则仍将调用先前查询的那些error处理程序。

Remedy 补救

While I have no practical experience with the mysql library, the first thing hitting me is that you are completely ignoring the err parameter of your connection.query() callback. 虽然我对mysql库没有任何实践经验,但首先令我感到震惊的是,您完全忽略了connection.query()回调的err参数。 You must not ignore these, unless you would like to spend hours of debugging a seemingly valid piece of code. 除非您想花费大量时间调试看似有效的代码,否则您不能忽略这些内容。

It would seem that instead of attaching an error handler to the connection , you simply check the err argument. 这似乎不是一个连接error处理程序的connection ,您只需检查err的说法。

PS. 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). 通常的做法是始终将在执行过程中发生的任何错误作为基于回调的API中的第一个参数传递(在没有错误的情况下指定null )。 Your callback function seems to not adhere to this practice. 您的callback函数似乎不遵循这种做法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM