【发布时间】:2014-11-09 06:48:48
【问题描述】:
我正在使用 express 4.x,以及最新的 MySQL node 包。
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
});
这个问题:
- 仍然无法缩放。在我的生产设备(1gb-2gb RAM,3.0ghz 四核 CPU)上,一个连接很容易被超过 10-20 个请求阻塞。
- 连接仍然会在一段时间后超时,我必须提供一个错误处理程序来捕获它并重新连接 - 非常笨拙。
我的问题是,在快速应用程序中处理数据库连接应该采取什么样的方法?它需要扩展(不是无限的,只是在合理范围内),我不应该在路由中手动关闭/为每条路径包含额外的中间件,而且我(最好)不想捕获超时错误并重新打开它们。
【问题讨论】:
-
我推荐你阅读sequelizejs.com
-
您的问题可能取决于您在“中间件”区域所做的工作。您查询的规模是多少:每秒查询次数是否很多?您是否对许多查询重复使用相同的连接?如果您要提出许多请求,您可能需要结帐pooling。池化时,请确保在完成连接后将连接释放回池中。
标签: mysql node.js express node-mysql