节点 js 应用程序中 db 连接池处理的最佳实践?
Posted
技术标签:
【中文标题】节点 js 应用程序中 db 连接池处理的最佳实践?【英文标题】:Best practices of db connection pool handling in a node js app? 【发布时间】:2016-02-13 17:48:53 【问题描述】:我指的是下面的node-postgres包,但我想这个问题比较笼统。
有一个琐碎的example,您 1) 从顶层 http 请求处理程序的池中获取(连接)一个连接(客户端),2)在该处理程序内部执行所有业务,3)将其释放回完成后的游泳池。
我想这个例子可以正常工作,但是一旦你的应用变得有点大,这很快就会变得痛苦。
我正在考虑这两个选项,但我不太确定......
在我需要与 db 交谈的任何地方都采用“获取客户端 + 工作 + 发布客户端”的方法。
这似乎是一个不错的选择,但它不会导致每个*** http 请求占用一个以上的连接/客户端(我的项目中的许多地方都有并行异步数据库调用)?
尝试将全局共享引用分配给可通过require()
访问的一个客户端/连接
这是一个好主意并且实际上可行吗?是否可以在所有丑陋的情况下很好地处理“返回池释放”(例如并行异步内容中的错误)?
谢谢。
【问题讨论】:
不要那样做。相反,请相信像 pg-promise 这样的高级库会自动为您完成所有这些工作。 谢谢@vitaly-t,我会看看pg-promise 我曾开发过几个 Web 应用程序,可以告诉您,每个使用 pin-a-db-connection-to-the-request 模型的应用程序都不可避免地会遇到可扩展性问题。处理数据库资源。 (获取+使用+返回)在我的书中是优越的。可能出错的事情要少得多。 【参考方案1】:好吧,我花了一些时间试图弄清楚这一点。最后,经过一番考虑并受到John Papa's code 的影响,我决定使用这样的database
模块:
var Q = require('q');
var MongoClient = require('mongodb').MongoClient;
module.exports.getDb = getDb;
var db = null;
function getDb()
return Q.promise(theDb);
function theDb(resolve, reject, notify)
if (db)
resolve(db);
else
MongoClient.connect(mongourl, mongoOptions, function(err, theDb)
resolve(db);
);
所以,当我需要执行查询时:
getDb().then(function(db)
//performe query here
);
至少对于 Mongodb 而言,这是一种很好的做法,正如 here 所见。
【讨论】:
感谢您的回答。我没有尝试过你的代码,但我想我明白了。您正在展示如何拥有一个全局数据库实例(我原来的问题中的第 2 点)。但是,发布是如何完成的(如果有 mongoclient 有这样的事情)? 我不知道需要在 Mongo 中发布,在答案中忘记了这一点。看起来这个解决方案对 Postgres 不利。【参考方案2】:最好的建议取决于数据库的类型和代表数据库的基本框架。
对于 Postgres,基本框架/驱动程序是 node-postgres,它具有对连接池的嵌入式支持。然而,这种支持是低级的。
有关高级访问权限,请参阅pg-promise,它提供自动连接管理,支持tasks、transactions 等等。
【讨论】:
【参考方案3】:这对我来说效果很好。
var pg = require('pg');
var config = pg : 'postgres://localhost/postgres' ;
pg.connect(config.pg, function(err, client, done)
client.query('SELECT version();', function (err, results)
done();
//do something with results.rows
);
);
【讨论】:
以上是关于节点 js 应用程序中 db 连接池处理的最佳实践?的主要内容,如果未能解决你的问题,请参考以下文章
在 go http 的自定义处理程序中传递 *gorm.db 实例的最佳实践