node.js - 在 NodeJS 中防止 MongoDB 多个连接
问题描述
我看过一些关于这个主题的帖子;其中之一帮助我取得了进步——但我仍然有一个问题。
我的 Mongo 数据库充斥着连接并抛出错误。我确实有多个不同的连接,我正在使用客户名称建立这些连接。在网上我发现了这个有用的类:
export default class ConnectionManager {
static databases: any = {};
static getConnection(customer: string) : Promise<typeof mongoose> {
if (this.databases[customer]) return Promise.resolve(this.databases[customer]);
return new Promise<typeof mongoose>((resolve: any, reject: any) => {
mongoose.connect(process.env.MONGOOSE_BASE_SERVER_URL + customer, { useNewUrlParser: true })
.then((newDb: mongoose.Mongoose) => {
this.databases[customer] = newDb;
resolve(this.databases[customer]);
});
});
}
}
正如我所提到的,这很有帮助——如果连接已经存在,它就可以工作。
问题是我有一个计划任务,它可能会在现有连接超时后立即用请求淹没 API。如果此时 API 充满了请求——它们来得太快,打开了数百个连接,我仍然遇到同样的问题;在 ConnectionManager.databases 有机会使用新连接进行更新之前。
绞尽脑汁想办法避免这种情况。有人有建议吗?
谢谢,
编辑 - 认为这主要发生在服务重启后。这是一个示例错误:
{ Error: read ECONNRESET
at TCP.onread (net.js:660:25)
name: 'MongoNetworkError',
errorLabels: [ 'TransientTransactionError' ],
[Symbol(mongoErrorContextSymbol)]: {} }
{ MongoNetworkError: connection 202 to localhost:27017 closed
at Socket.<anonymous> (.../node_modules/mongodb-core/lib/connection/connection.js:275:9)
at Object.onceWrapper (events.js:273:13)
at Socket.emit (events.js:182:13)
at TCP._handle.close (net.js:599:12)
name: 'MongoNetworkError',
errorLabels: [ 'TransientTransactionError' ],
[Symbol(mongoErrorContextSymbol)]: {} }
解决方案
Promise 自然地提供缓存行为,因为已解决的 Promise 在链接时提供相同的结果。
一种正确的方法是将承诺存储在 中databases
,这样就不会出现导致多个同名连接的竞争条件,即databases[customer] = Promise.resolve(mongoose.connect(...))
.
但这对于内部链接连接承诺的 Mongoose 来说是不需要的;连接对象可以只保存和使用。使用方法创建多个连接createConnection
。
此外,仅静态类是反模式。它可以是一个对象或只是一个函数:
export const _databases = {};
export const getConnection = (customer) => {
if (!_databases[customer])
_databases[customer] = mongoose.createConnection(
process.env.MONGOOSE_BASE_SERVER_URL + customer,
{ useNewUrlParser: true }
);
return _databases[customer];
}
databases
对象是公共出口没有明显的理由。它可以导出用于测试目的。
推荐阅读
- c# - System.Text.Json 序列化 Unicode 字符(如表情符号)的问题
- .net - 为什么为日期类型对象分配一个值不能正确地获得它的值?
- python - 如何生成包含连续数字和字母混合的列表?
- javascript - Three.js中点的局部到全局(反之亦然)矩阵变换
- autodesk-forge - 为什么我的线宽不显示在 2D Forge Viewer 中?
- python - 与其他表达式进行 OR 运算时,Python 正则表达式与组不匹配
- php - MethodNotAllowedHttpException 在另一个类服务中调用 Model::create
- java - 使用 IP 地址到远程服务器的 JDBC 连接
- c# - 如何使用 C# selenium 绕过这层 javascript?
- python - Django分页与输入查询不匹配