猫鼬太多的连接和命令
Mongoose too many connection and commands
我是来寻求 mongo/mongoose 方面的帮助的。我使用访问 mongo 数据库的 AWS lambda,有时我的连接数达到 500 的限制时遇到问题。我正在尝试解决这个问题,我做了一些类似这样的事情 https://dzone.com/articles/how-to-use-mongodb-connection-pooling-on-aws-lambd and https://www.mongodb.com/blog/post/optimizing-aws-lambda-performance-with-mongodb-atlas-and-nodejs。这基本上是使用类似单例的设置 context.callbackWaitsForEmptyEventLoop = false
,这确实有帮助,但仍然很少在不到一分钟的时间内打开 100 个连接,看起来有些连接没有被重用,即使我们的日志显示它们正在被重用。所以我意识到一个奇怪的行为,每当 mongoatlas 显示命令数量增加时,我的 mongo 连接就会大量增加。第一个图表是操作,第二个是连接。
查看操作,命令太多,查询很少。我不知道这些命令是什么,我的理论是这些命令导致了问题,但我没有找到任何东西来解释查询和命令之间的区别,让我知道这是否是一个有效的理论。还有就是,如何正确选择pool size的个数,我们有非常简单的查询。
这是我们的单例 class 因为也许这就是我们做错的地方:
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;
}
}
我希望这些信息足够了。我的主要问题是我的命令导致太多连接的理论是否可能以及命令到底是什么,因为我发现的每个解释看起来都与查询相同。
根据 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;
}
我是来寻求 mongo/mongoose 方面的帮助的。我使用访问 mongo 数据库的 AWS lambda,有时我的连接数达到 500 的限制时遇到问题。我正在尝试解决这个问题,我做了一些类似这样的事情 https://dzone.com/articles/how-to-use-mongodb-connection-pooling-on-aws-lambd and https://www.mongodb.com/blog/post/optimizing-aws-lambda-performance-with-mongodb-atlas-and-nodejs。这基本上是使用类似单例的设置 context.callbackWaitsForEmptyEventLoop = false
,这确实有帮助,但仍然很少在不到一分钟的时间内打开 100 个连接,看起来有些连接没有被重用,即使我们的日志显示它们正在被重用。所以我意识到一个奇怪的行为,每当 mongoatlas 显示命令数量增加时,我的 mongo 连接就会大量增加。第一个图表是操作,第二个是连接。
查看操作,命令太多,查询很少。我不知道这些命令是什么,我的理论是这些命令导致了问题,但我没有找到任何东西来解释查询和命令之间的区别,让我知道这是否是一个有效的理论。还有就是,如何正确选择pool size的个数,我们有非常简单的查询。
这是我们的单例 class 因为也许这就是我们做错的地方:
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;
}
}
我希望这些信息足够了。我的主要问题是我的命令导致太多连接的理论是否可能以及命令到底是什么,因为我发现的每个解释看起来都与查询相同。
根据 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;
}