节点js。创建连接的正确/最佳实践

时间:2017-01-03 06:39:57

标签: javascript mysql node.js

现在我正在Node JS中创建一个非常大的应用程序。我试图让我的代码干净简洁(就像大多数开发人员一样)。我已经创建了自己的js文件来处理与mysql的连接。请参阅下面的代码。

var mysql = require('mysql');

var config = {
    'default' : {
        connectionLimit : process.env.DB_CONN_LIMIT,
        host     : process.env.DB_HOST,
        user     : process.env.DB_USER,
        password : process.env.DB_PASS,
        database : process.env.DB_NAME,
        debug    : false,
        socketPath  : process.env.DB_SOCKET
    }
};

function connectionFunc(query,parameters,callback,configName) {

    configName = configName || "default";

    callback = callback || null;

    parameters = parameters;

    if(typeof parameters == 'function'){

        callback = parameters;

        parameters = [];

    }
    //console.log("Server is starting to connect to "+configName+" configuration");
    var dbConnection = mysql.createConnection(config[configName]);

    dbConnection.connect();

    dbConnection.query(query,parameters, function(err, rows, fields) {
      //if (!err)
        callback(err,rows,fields);
      //else
        //console.log('Error while performing Query.');
    });

    dbConnection.end();
}

module.exports.query = connectionFunc;

我在我的模型中使用上述文件,如下所示:

var database = require('../../config/database.js');

module.exports.getData = function(successCallBack){
    database.query('SAMPLE QUERY GOES HERE', function(err, result){
        if(err) {console.log(err)}
        //My statements here
    });
}

使用这种编码风格,一切正常,但是当我试图创建一个函数时,由于某种原因会循环我的模型的方法。请参阅以下示例:

for (i = 0; i < 10000; i++) {
    myModel.getData(param, function(result){             
        return res.json({data : result }); 
    });
}

它给了我一个ER_CON_COUNT_ERROR : Too Many Conenction。问题是为什么当我的连接始终以dbConnection.end();结束时,我仍然会收到类似这样的错误?我还不确定我是否遗漏了什么。我仍然坚持这个。 我的连接限制为100,我认为添加更多连接是一个坏主意。

1 个答案:

答案 0 :(得分:0)

因为数据库中的查询数据是异步的。

在你的循环中,myModel.getData(或者更确切地说是基础query)将不会暂停/ paus你的代码,直到查询完成,但是将查询发送到数据库服务器并且尽快数据库响应将调用回调。

end上的调用dbConnection不会立即关闭连接,只要所有使用该连接创建的查询都已完成,它就会标记要关闭的连接。

mysql: Terminating connections

  

通过调用 end()方法来正常终止连接。这将确保在将COM_QUIT数据包发送到MySQL服务器之前,所有先前排队的查询仍然存在。

     

结束连接的另一种方法是调用 destroy()方法。这将导致立即终止底层套接字。另外,destroy()保证不再为连接触发事件或回调。

但是使用destroy时,库不会等待结果,因此结果会丢失,destroy很少有用。

因此,使用您给定的代码,您尝试一次创建10000个连接。

您应该只使用任务连接,例如如果用户使用浏览器请求数据,那么您应该为此给定请求使用一个连接。如果您在某些时间间隔内完成某项任务,那么定时任务也是如此。

这是一个示例代码:

var database = require('./config/database.js');

function someTask( callback ) {
   var conn = database.getConnection();

   myModel.getData(conn, paramsA, dataReceivedA)

   function dataReceivedA(err, data) {
       myModel.getData(conn, paramsB, dataReceivedB)
   }

   function dataReceivedB(err, data) {
      conn.end()
      callback();
   }
}

如果要在模型代码中完全隐藏数据库连接。然后你需要这样做:

var conn = myModel.connect();
conn.getData(params, function(err, data) {
   conn.end();
})

如何实际解决这个问题只取决于很多因素,所以只能在这里给你提示。