NodeJS + ExpressJS正确的方法来管理与mysql DB的连接

时间:2019-06-09 09:32:53

标签: mysql node.js reactjs express mariadb

我正在使用ReactJS / NodeJS + ExpressJS开发应用程序。

我试图了解什么是处理数据库连接的最佳方法。这段代码有效,但似乎它不断增加连接数,我认为这不是很好,但是您可能会启发我。

当我刚启动mysql服务器(不运行我的应用程序)时,连接已经60个了,

MariaDB [(none)]> show status like 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 60    |
+-----------------------------------+-------+
7 rows in set (0.001 sec)

然后,一旦我运行我的应用程序,连接就会增加到64:

MariaDB [(none)]> show status like 'Conn%';
+-----------------------------------+-------+
| Variable_name                     | Value |
+-----------------------------------+-------+
| Connection_errors_accept          | 0     |
| Connection_errors_internal        | 0     |
| Connection_errors_max_connections | 0     |
| Connection_errors_peer_address    | 0     |
| Connection_errors_select          | 0     |
| Connection_errors_tcpwrap         | 0     |
| Connections                       | 64    |
+-----------------------------------+-------+
7 rows in set (0.000 sec)

然后,每次我重新启动后端应用程序或从前端发出请求时,连接数量似乎都会增加。

我不确定如何管理连接,我承认我使用的代码的某些部分对我来说不是很清楚(我是新来的反应,表达和节点),所以请耐心等待。< / p>

这是我正在使用的代码的一部分,希望您能帮助我找到管理连接的最佳方法。

由于connection将在我的应用程序的多个区域中使用,因此我创建了一个包含以下内容的.js文件:

class Connection {

    static connect() {

        var mysql = require('mysql');
        var connection = null;

        var connection_settings = {
            host     : 'localhost',
            database : '..',
            user     : '..',
            password : '..',
        }

        connection = mysql.createConnection(connection_settings);

        connection.connect(function(err) {
            if(err) {
                console.log('error when connecting to db:', err);
            } 
        });

        return connection;

    }

}

module.exports = { Connection }

然后是包含查询数据库代码的文件:

const { Connection } = require('../database.js')

function openLessonSections (lessonID, connection){

    return new Promise(function (resolve, reject){
        const sql = "SELECT * FROM sections WHERE lesson_id=" + lessonID;
        connection.query (sql, function (error, result){
            console.log('Loading lesson "' + lessonID + '".');
            if (error) reject (error);
            resolve (result);
        });
    });
}

async function openLesson(lessonID, connection){
    return await openLessonSections(lessonID, connection);
}

exports.lessonOpen = function(req, res, next) {

    const connection = Connection.connect();

    console.log('request received');

    const lessonID = JSON.parse(req.body.lessonID);

    console.log('Opening lesson: ' + lessonID);

    openLesson(lessonID, connection)
        .then(function(result){
            console.log('The lesson was opened successfully.');
            res.status(200).json({sections: result});
        })
        .catch(function (error){
            res.status(500).json(error);
            console.log('There was an error while opening the lesson. ' + error);
        });

    connection.end();

}

我知道自己做错了事,对于什么是最佳方法我有些困惑。谢谢您的帮助。

2 个答案:

答案 0 :(得分:1)

树错了树。

STATUS Connections是一个计数器,它在服务器(mysqld)启动时从零开始。 Connections/Uptime更有趣-可能约为每秒1或每小时1。我已经看到Connections超过10亿,但是服务器已经运行了几周。

另一方面,可能有某种形式的“连接池”,但是可能由堆栈中的几个组件中的任何一个引入。

  

我试图了解什么是处理与数据库连接的最佳方法。

简单的答案是“不用担心”。

在大多数情况下,一个网页应该包含一个 MySQL / MariaDB连接。如果您的代码建立一个网页的多个连接,则效率低下。您似乎通过各种JS组件来回穿梭?可能没有保存“状态”,因此他们可能必须进行单独的连接。绘制一个“数据流”图(或列出一个列表)。如果来回“太多”,那是“不好”。普通网页具有 one 连接,构建整个页面,然后消失。但是,对于JS和AJAX来说,来回做的很诱人-当需要交互时,请 except 拒绝它。

答案 1 :(得分:1)

一种选择是创建连接池(一次):

const mysql = require('mysql');
const pool = mysql.createPool({
  host: 'myhost',
  user: 'myuser',
  password: 'mypass',
  database: 'mydb',
  connectionLimit: 10,
  supportBigNumbers: true
})

然后,每当您运行查询时,都会从池中获取连接:

function query(sql, args) {
  return new Promise((resolve, reject) => {
    pool.getConnection(function(err, connection) {
      if (err) {
        return reject(err);
      }
      connection.query(sql, args, function(err, result) {
        connection.release();
        if (err) {
          return reject(err);
        }
        return resolve(result);
      });
    });
  });
}

导出query函数:

module.exports = {
  query
};

将所有内容放入一个模块中,在任何地方都需要它,然后根据需要使用query