Node.js 防止NodeJS中的MongoDB多连接
我看过一些关于这个话题的帖子;其中一个帮助了我的进步,但我仍然有一个问题 我的Mongo数据库中充斥着连接和抛出错误。我确实使用客户名称建立了多个不同的连接。我在网上发现了这个有用的课程:Node.js 防止NodeJS中的MongoDB多连接,node.js,database,mongodb,http,mongoose,Node.js,Database,Mongodb,Http,Mongoose,我看过一些关于这个话题的帖子;其中一个帮助了我的进步,但我仍然有一个问题 我的Mongo数据库中充斥着连接和抛出错误。我确实使用客户名称建立了多个不同的连接。我在网上发现了这个有用的课程: export default class ConnectionManager { static databases: any = {}; static getConnection(customer: string) : Promise<typeof mongoose> { if (thi
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]);
});
});
}
}
导出默认类ConnectionManager{
静态数据库:any={};
静态getConnection(客户:字符串):承诺{
if(this.databases[customer])返回Promise.resolve(this.databases[customer]);
返回新承诺((解决:任何,拒绝:任何)=>{
connect(process.env.mongoose_BASE_SERVER_URL+customer,{useNewUrlParser:true})
.then((newDb:mongoose.mongoose)=>{
this.databases[customer]=newDb;
解决(此数据库[客户]);
});
});
}
}
正如我所提到的,这很有帮助——如果连接已经存在,它就可以工作
问题是我有一个计划任务,在现有连接超时后,它可能会立即向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)]: {} }
{错误:读取EconReset
在TCP.onread(net.js:660:25)
名称:“MongoNetworkError”,
errorLabels:['TransientTransactionError'],
[符号(mongoErrorContextSymbol)]:{}
{MongoNetworkError:到本地主机的连接202:27017已关闭
在套接字上。(…/node\u modules/mongodb core/lib/connection/connection.js:275:9)
在Object.onceWrapper(events.js:273:13)
在Socket.emit(events.js:182:13)
在TCP._handle.close(net.js:599:12)
名称:“MongoNetworkError”,
errorLabels:['TransientTransactionError'],
[符号(mongoErrorContextSymbol)]:{}
承诺自然会提供缓存行为,因为解析的承诺在链接时提供相同的结果
适当的方法是将承诺存储在数据库中
,这样就不会出现导致多个同名连接的竞争条件,即数据库[customer]=Promise.resolve(mongoose.connect(…)
但猫鼬不需要这样做,因为猫鼬内部链接着连接承诺;可以只保存和使用连接对象。使用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];
}
没有明显的理由将数据库
对象公开导出。可以出于测试目的导出它