关于mysql数据库连接池的一个疑问,求在开发环境中使用过node连接mysql数据库的大神赐教
发布于 6 年前 作者 without-yy 3786 次浏览 来自 问答

目前使用node读取mysql中的数据,每次读取的时候都会pool.getConnection创建一个连接读取完数据再关闭下一次再重新打开, 问了下公司的后台不是写node的,说是要创建一个全局变量存储一个连接,每次操作直接用这个,如果连接失效了才会重新连接 求教下node下使用连接池的正确方式

//目前的代码是这样的
const mysql = require('promise-mysql');
const config = require('./config');


const pool = mysql.createPool({
    host: config.host,
    user: config.user,
    password: config.password,
    database: config.database,
    connectionLimit: 10
});
//这是之前使用的方式每次创建一个连接使用完关闭
function getDataFromSqlQuery(sql) {
    return new Promise((resolve, reject) => {
        pool.getConnection().then((connection) => {
            connection.query(sql).then(function (res) {
                resolve(res);
                pool.releaseConnection(connection);
                return;
            }).catch(err => {
                reject(err);
            });
        })
    });
}
//刚才尝试了下想直接把connection导出使用await函数接受,可还是做不到全局赋值只能在async函数中使用,使用完毕再关闭
function getConnection(sql) {
    return new Promise((resolve, reject) => {
        pool.getConnection().then((connection) => {
            resolve(connection);
        }).catch(err=>{
            reject(err);
        })
    });
}

module.exports = {
    pool : pool,
    getConnection : getConnection,
	getData:getDataFromSqlQuery
};

//调用
const sql = require('../modules/sql-connection.js');
router.post('/test', async function (next) {
    let start = new Date();

    let res = await sql.getData('select * from unsafeip limit 1');

    console.log(`${new Date() - start} ms`);

    this.body = res;
});


//测试服务器 阿里云北京服务器单核1G内存 坐标上海

//用for循环调用了下 不存在失败的情况
for (let i = 0, len = 10000; i < len; i++) {
    (async function (i,start) {
        try {
            let res = await getDataFromSqlQuery('select * from unsafeip limit 1');
            console.log(`${i} : ${new Date() - start} ms`);
        }catch (e){
            console.log(e);
            console.log(`第${i}次请求失败`);
        }
    })(i+1,new Date())
}
//1000次的结果  :  6269 ms
/**最终结果 9991 : 63803 ms
9993 : 63803 ms
9996 : 63812 ms
9997 : 63838 ms
9998 : 63842 ms
9999 : 63849 ms
10000 : 63856 ms
*/

//创建一个连接一直用同一个
(async function () {
    let connection =await getConnection();
    for (let i = 0, len = 1000; i < len; i++) {
        (async function (i,start) {
            try {
                let res = await connection.query('select * from unsafeip limit 1');
                console.log(`${i} : ${new Date() - start} ms`);
            }catch (e){
                console.log(e);
                console.log(`第${i}次请求失败`);
            }

        })(i,new Date())

    }
})();
//  结果 999 : 30301 ms 


//结果发现每次打开关闭比一直使用一个连接连接速度更快  不纠结这个问题了


4 回复

连接池,是保持一定数量的连接,随时都可以拿来用;用同一个连接,可不得等别人用完了再拿来用么…后端多半说的是单例模式吧

连接池你就认为它是一个池子,这个池子里有多个连接(数量在创建连接池的时候可指定,默认应该是10个),当程序需要操作数据库的时候首先从连接池里拿看看有没有空闲的连接(一个连接从pool.getConnection()开始到release执行前都是非空闲的连接):如果有则直接拿来用,用完再release这个连接就回到连接池了(在连接池里存活时间默认是8小时,这个值在数据里可配,即8小时内无任何程序使用它,则被数据库回收)。如果没有,首先判断当前连接池里连接是否满,如果满了的话要么一直等待要么报错(这个在创建连接池的时候也可以配置是报错还是等待),如果没满则从数据拿一个新的连接用完release后就会到连接池里。

补充一句:如果你不需要用到事务等这种需要保证连接唯一的话,你可以直接用pool执行你的sql语句,即pool.query('sql_str')。 因为pool是自动释放的,不需要主动release

@imhered 就是说pool是已经维护好的链接池直接用就可以了么,不需要手动维持几个连接吗

回到顶部