【问题标题】:Preventing MongoDB Multiple Connections in NodeJS在 NodeJS 中防止 MongoDB 多个连接
【发布时间】:2019-01-31 07:29:39
【问题描述】:

我看过一些关于这个主题的帖子;其中之一帮助我取得了进步 - 但我仍然遇到问题。

我的 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)]: {} }

【问题讨论】:

    标签: node.js database mongodb http mongoose


    【解决方案1】:

    Promises 自然地提供缓存行为,因为已解决的 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 对象没有明显的理由公开导出。它可以导出用于测试目的。

    【讨论】:

      猜你喜欢
      • 2014-08-13
      • 2018-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-09
      • 2016-03-04
      相关资源
      最近更新 更多