我已经看到了有关该主题的几篇文章;其中之一帮助我进步了-但我仍然有问题。
我的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)]: {} }
答案 0 :(得分:2)
承诺自然会提供缓存行为,因为已解决的诺言在链接时会提供相同的结果。
一种正确的方法是将诺言存储在{{1}}中,这样就不会出现导致多个同名连接(即databases
)的竞争条件。
但是对于内部连接连接承诺的猫鼬来说,这不是必需的。连接对象可以保存和使用。使用databases[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];
}
对象公开导出的明显理由。可以将其导出以进行测试。