node.js - 防止 NodeJS 中的 MongoDB 多重连接

标签 node.js database mongodb http mongoose

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

我的 Mongo 数据库充满了连接和抛出错误。我确实有多个不同的连接,我正在使用客户名称建立这些连接。我在网上找到了这个有用的类(class):

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 在链接时提供相同的结果。

一个合适的方法是将 promises 存储在 databases 中,这样就不会出现导致多个同名连接的竞争条件,即 databases[customer] = Promise .resolve(mongoose.connect(...)).

但这对于在内部链接连接 promise 的 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 对象被公开导出。它可以导出用于测试目的。

关于node.js - 防止 NodeJS 中的 MongoDB 多重连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52010857/

相关文章:

node.js - 按需require()

javascript - Node.js 服务中的 socket.io 事件使用的套接字

Java:结果集更新不更新数据库

node.js - Mongoose 不允许我为 Number 插入空值?

mongodb - 一次更新多个 - 但部分 - 对象字段而不替换整个文档(Spring 3.1 和 MongoDB 的 MongoTemplate)

java - 如何在单个查询对象 Mongodb Spring 数据中添加 or & 和 Criteria 子句

node.js - 在 Istio/kubernetes 中需要自定义身份验证方面的帮助

javascript - Node.js/Express - 如何设置响应字符编码?

java - 在 Java 中执行 MySQL 查询时出错

数据库内部 - 从哪里开始?