【问题标题】:Mongoose too many connection and commands猫鼬太多的连接和命令
【发布时间】:2021-06-18 22:28:04
【问题描述】:

我在这里请求有关 mongo/mongoose 的帮助。我使用访问 mongo 数据库的 AWS lambda,有时我的连接数达到 500 的限制时遇到问题。我正在尝试解决这个问题,我做了一些类似 https://dzone.com/articles/how-to-use-mongodb-connection-pooling-on-aws-lambdhttps://www.mongodb.com/blog/post/optimizing-aws-lambda-performance-with-mongodb-atlas-and-nodejs 的事情。这基本上是使用类似单例并设置context.callbackWaitsForEmptyEventLoop = false,这确实有帮助,但仍然很少在不到一分钟的时间内打开100个连接,看起来即使我们的日志显示有些连接也没有被重用他们正在被重复使用。所以我意识到一个奇怪的行为,每当 mongoatlas 向我显示增加的命令数量时,我的 mongo 连接就会大量增加。第一个图表是操作,第二个是连接。

看操作​​,命令太多,查询很少。我不知道这些命令是什么,我的理论是这些命令导致了问题,但我没有找到任何解释查询和命令之间有什么区别的东西,让我知道这是否是一个有效的理论。另一件事是,如何正确选择池大小的数量,我们有非常简单的查询。

这是我们的单例类,因为也许这是我们做错了:

class Database {
  options: [string, mongoose.ConnectionOptions];
  instance?: typeof mongoose | null;

  constructor(options = config) {
    console.log('[DatabaseService] Created database instance...');
    this.options = options;
    this.instance = null;
  }

  async checkConnection() {
    try {
      if (this.instance) {
        const pingResponse = await this.instance.connection.db.admin().ping();

        console.log(`[DatabaseService] Connection status: ${pingResponse.ok}`);

        return pingResponse.ok === 1;
      }

      return false;
    } catch (error) {
      console.log(error);

      return false;
    }
  }

  async init() {
    const connectionActive = await this.checkConnection();
    if (connectionActive) {
      console.log(`[DatabaseService] Already connected, returning instance`);
      return this.instance;
    }
    console.log('[DatabaseService] Previous connection was not active, creating new connection...');
    this.instance = await mongoose.connect(...this.options);
    const timeId = Date.now();
    console.log(`Connection opened ${timeId}`);
    console.time(`Connection started at ${timeId}`);
    this.instance?.connection.on('close', () => {
      console.timeEnd(`Connection started at ${timeId}`);
      console.log(`Closing connection ${timeId}`);
    });
    return this.instance;
  }

  async getData(id: string) {
    await this.init();
    const response = await Model.findOne({ 'uuid': id });
    return response;
  }
}

我希望这是足够的信息。我的主要问题是我的命令理论是否可能导致过多的连接,以及究竟什么是命令,因为我发现的每个解释看起来都与查询相同。

【问题讨论】:

  • 这会在每次查询之前运行一个 ping 管理员“命令”。为什么要添加连接管理? Mongo 通常会为您管理所有这些,这就是在 lambda 函数之外设置“单例”的原因。
  • 我自己还没有实现,但我不应该检查一下吗?我的意思是,如果连接由于任何其他原因超时而关闭,并且我调用了一个 find 函数,mongo 只会自己打开一个新函数?
  • 你好@Matt 我已经删除了单例验证,基本上它解决了我的问题,所以如果你想回答,我会标记为正确答案。

标签: node.js mongoose aws-lambda mongodb-atlas


【解决方案1】:

根据 Matt 写的评论,我更改了我的 init 函数,现在我的连接受到控制。

async init() {
    if (this.instance) {
      console.log(`[DatabaseService] Already connected, returning instance`);
      return this.instance;
    }
    console.log('[DatabaseService] Previous connection was not active, creating new connection...');
    this.instance = await mongoose.connect(...this.options);
    const timeId = Date.now();
    console.log(`Connection opened ${timeId}`);
    console.time(`Connection started at ${timeId}`);
    this.instance?.connection.on('close', () => {
      console.timeEnd(`Connection started at ${timeId}`);
      console.log(`Closing connection ${timeId}`);
    });
    return this.instance;
  }

【讨论】:

    猜你喜欢
    • 2015-12-30
    • 1970-01-01
    • 1970-01-01
    • 2016-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-25
    相关资源
    最近更新 更多