用于在快速应用程序中处理MySQL数据库连接的模式

时间:2014-09-15 17:06:28

标签: mysql node.js express node-mysql

我正在使用express 4.x和节点的最新MySQL包。

PHP应用程序(我最熟悉的)的模式是包含某种数据库连接公共文件,并在脚本完成后自动关闭连接。在Express应用程序中实现它时,它可能看起来像这样:

// includes and such
// ...
var db = require('./lib/db');

app.use(db({
  host: 'localhost',
  user: 'root',
  pass: '',
  dbname: 'testdb'
}));

app.get('/', function (req, res) {
  req.db.query('SELECT * FROM users', function (err, users) {
    res.render('home', {
      users: users
    });
  });
});

请原谅缺乏错误处理,这是一个原始的例子。在任何情况下,我的db()函数都会返回将连接到数据库并存储连接对象req.db的中间件,从而有效地为每个请求提供一个新对象。这种方法存在一些问题:

  • 这根本不规模;数据库连接(价格昂贵)将以相当便宜的请求线性扩展。
  • 数据库连接不会自动关闭,如果未捕获的错误消失,将终止应用程序。你必须抓住它并重新连接(感觉像反模式)或者写一些中间件,一切都必须将pior称为输出以确保连接关闭(反DRY,可以说是)

我看到的下一个模式是在应用启动时简单地打开一个连接。

var mysql = require('mysql');

var connection = mysql.createConnection(config);
connection.on('connect', function () {
  // start app.js here
});

问题:

  • 仍然没有扩展。在我的生产箱上只有10-20个请求(1gb-2gb RAM,3.0ghz四CPU),一个连接很容易堵塞。
  • 一段时间后连接仍然会超时,我必须提供一个错误处理程序来捕获它并重新连接 - 非常糟糕。

我的问题是,在快递应用程序中处理数据库连接应该采取什么样的方法?它需要扩展(不是无限的,只是在合理范围内),我不应该在路由中手动关闭/包含每个路径的额外中间件,并且我(最好)不想捕获超时错误并重新打开它们。

1 个答案:

答案 0 :(得分:1)

既然你在NodeJS中谈论MySQL,我必须指向你KnexJS!你会发现写作查询更有趣。他们使用的另一件事是连接池,它可以解决您的问题。它正在使用一个名为generic-pool-redux的小包来管理数据库连接等事情。

我们的想法是,您的快递应用程序通过代码访问数据库。事实证明,该代码使用连接池来共享连接之间的负载。我初始化我的东西:

var Knex = require('knex');
Knex.knex = Knex({...}); //set options for DB

在其他档案中

var knex = require('knex').knex;

现在所有可以访问数据库的文件都使用相同的连接池(在开始时设置一次)。


我确定Node和MySQL还有其他连接池包,但如果您正在进行任何动态或复杂的SQL查询,我个人推荐使用KnexJS。祝你好运!