NodeJs - 如何在我的模型中共享MySQL池以避免' ER_CON_COUNT_ERROR'

时间:2017-08-25 21:34:37

标签: mysql node.js connection-pooling

我目前正在使用ApacheBench测试我的节点应用。我遇到了一个问题,我的数据库是ER_CON_COUNT_ERROR: Too many connections

我在MySQL节点模块的顶部使用了一个短库,你可以在下面看到

var mysql = require('mysql');
var config = require('path/to/config');
var message = require('./myMessageLib.js');

var pool = mysql.createPool({
    connectionLimit : 100,
    host: config.db.mysql.host,
    user: config.db.mysql.user,
    password: config.db.mysql.password,
    database: config.db.mysql.database
});

var query = function(query_str, values, next) {
    pool.getConnection((err, connection) => {
        if (err) {
            console.error("MySQL Fail to get a connection in pool : " + err);
            if (typeof connection !== "undefined")
                connection.release();
            next(error, null);
            return ;
        }
        connection.query(query_str, values, function(error, data, fields) {
            connection.release();
            if (error) 
                if (config.app.env.dev)
                    throw (error);
                else {
                    next(error, null);
                    return (message.error("MySQL query failed : " + query_str + " / err : " + error));
                }
            if (data.length == 0)
                next(null);
            else
                next(data);
        })
    })
}

exports.query = query;

我通过做这样的事情在我的模型中使用这个库

var mysql = require('path/to/mysqllib');

/**
 * Class PlayerModel
 */
function PlayerModel() { };

PlayerModel.prototype.get = function(id, next) {
    mysql.query("SELECT ....", [id], function(player) {
        // stuff
    })
}

module.exports = PlayerModel;

我的主页上的内容我使用了上面提到的不同模型,每个模型都启动查询以获取一些数据库信息。当我启动只有50个并发级别的ApacheBench时,我得到了ER_CON_COUNT_ERROR:连接太多。所以我觉得游泳池没有做好,因为它似乎并不尊重短篇MySQL库中写的100的连接限制。

我正在考虑在global nodejs变量中创建和存储池,以便能够正确地分享我的模块,但我不确定它是一个好方法,也许我也是#39;我在我的游泳池实施中做错了什么。

你有任何想法或改进建议吗?

感谢队友!

2 个答案:

答案 0 :(得分:0)

我想出了这个问题。

我的应用正在以群集模式部署。两个进程同时运行。因此,可能已经创建了两个100个连接的池,这导致总共200个连接高于MySQL默认连接限制。

答案 1 :(得分:0)

很棒,找到了一个解决方案,而这是另一个代码较少的解决方案。

创建一个js文件,例如 dbconnection.js

var mysql   = require("mysql");

var pool = mysql.createPool({
    connectionLimit: 10,
    host: '...',
    user: '...',
    password: '...',
    database: '...',
    dateStrings: true
});

exports.connection = {
    query: function () {
        var queryArgs = Array.prototype.slice.call(arguments),
            events = [],
            eventNameIndex = {};

        pool.getConnection(function (err, conn) {
            if (err) {
                if (eventNameIndex.error) {
                    eventNameIndex.error();
                }
            }
            if (conn) { 
                var q = conn.query.apply(conn, queryArgs);
                q.on('end', function () {
                    conn.release();
                });

                events.forEach(function (args) {
                    q.on.apply(q, args);
                });
            }
        });

        return {
            on: function (eventName, callback) {
                events.push(Array.prototype.slice.call(arguments));
                eventNameIndex[eventName] = callback;
                return this;
            }
        };
    }
};

在您要使用连接的另一个文件中

var db = require('./dbconnection.js');

而不是

connection.query

使用

db.connection.query