使用Mongoose与NodeJs时遭遇MongoPoolClosedError问题求助
解决MongoPoolClosedError:尝试从已关闭的连接池获取连接的问题
错误信息
MongoPoolClosedError: Attempted to check out a connection from closed connection pool at ConnectionPool.processWaitQueue (C:\Proyectos\SinergiaCRM\sinergiaDA\SinergiaDA\eda\sda_api\node_modules\mongodb\src\cmap\connection_pool.ts:757:37) at ConnectionPool.close (C:\Proyectos\SinergiaCRM\sinergiaDA\SinergiaDA\eda\sda_api\node_modules\mongodb\src\cmap\connection_pool.ts:509:10) at Server.destroy (C:\Proyectos\SinergiaCRM\sinergiaDA\SinergiaDA\eda\sda_api\node_modules\mongodb\src\sdam\server.ts:264:17) at destroyServer (C:\Proyectos\SinergiaCRM\sinergiaDA\SinergiaDA\eda\sda_api\node_modules\mongodb\src\sdam\topology.ts:773:10) at node:internal/util:375:7 at new Promise (<anonymous>) at destroyServer (node:internal/util:361:12) at C:\Proyectos\SinergiaCRM\sinergiaDA\SinergiaDA\eda\sda_api\node_modules\mongodb\src\sdam\topology.ts:506:38 at Function.from (<anonymous>) at Topology.close (C:\Proyectos\SinergiaCRM\sinergiaDA\SinergiaDA\eda\sda_api\node_modules\mongodb\src\sdam\topology.ts:505:36)
我的代码实现
连接方法
public mongoEdaConnect(req: Request) { mongoose.set('strictQuery', false) let con = this.connector(req).mongodb mongoose.connect(con, {}) .then(() => console.log("conectado a mongo")) .catch(err => console.log(err)) }
断开连接方法
public mongoEdaDisconnect() { mongoose.disconnect().then(()=> console.log("Desconectado de mongo")) }
调用方式
const mongoConnector = new Connections() try { mongoConnector.mongoEdaConnect(req) } catch (err) { if (err) throw err console.log("no conectado") }
mongoConnector.mongoEdaDisconnect()
问题背景
调用断开连接方法时就会触发上述错误,改用异步调用后问题依旧。如果注释断开连接代码,服务器能正常运行,但因需要在同一服务器运行多个站点,必须能正常关闭连接。
解决方案
1. 确保异步操作顺序执行
连接和断开方法都是异步操作,但原调用未等待操作完成,可能导致连接未建立就执行断开,或断开时仍有未完成的数据库请求。修改为异步并使用await等待:
修改后的连接方法
public async mongoEdaConnect(req: Request): Promise<void> { mongoose.set('strictQuery', false); const con = this.connector(req).mongodb; try { await mongoose.connect(con, {}); console.log("conectado a mongo"); } catch (err) { console.error(err); throw err; } }
修改后的断开方法
public async mongoEdaDisconnect(): Promise<void> { try { await mongoose.disconnect(); console.log("Desconectado de mongo"); } catch (err) { console.error(err); throw err; } }
正确调用方式
const mongoConnector = new Connections(); try { // 等待连接建立完成 await mongoConnector.mongoEdaConnect(req); // 执行所有数据库操作,确保操作全部完成后再断开 // ... 你的业务逻辑代码 ... } catch (err) { console.log("no conectado"); throw err; } finally { // 无论是否出错,都确保断开连接 await mongoConnector.mongoEdaDisconnect(); }
2. 使用独立连接实例(多站点场景推荐)
同一服务器运行多个站点时,全局mongoose连接会导致断开操作影响其他站点。建议为每个站点创建独立连接实例:
修改后的连接/断开方法
import mongoose, { Connection } from 'mongoose'; public async mongoEdaConnect(req: Request): Promise<Connection> { mongoose.set('strictQuery', false); const con = this.connector(req).mongodb; // 创建独立连接实例 const connection = await mongoose.createConnection(con, {}); console.log("conectado a mongo"); return connection; } public async mongoEdaDisconnect(connection: Connection): Promise<void> { // 关闭指定的连接实例 await connection.close(); console.log("Desconectado de mongo"); }
调用方式
const mongoConnector = new Connections(); let connection: Connection | undefined; try { connection = await mongoConnector.mongoEdaConnect(req); // 使用connection实例执行数据库操作,而非全局mongoose // const Model = connection.model('ModelName', schema); // ... 业务逻辑 ... } catch (err) { console.log("no conectado"); throw err; } finally { if (connection) { await mongoConnector.mongoEdaDisconnect(connection); } }
3. 排查未完成的数据库操作
错误本质是关闭连接池时仍有请求在等待获取连接,需确保断开前所有数据库查询、写入操作都已完成:
- 确保所有
find、create等数据库方法都用await等待完成 - 检查是否有定时任务或未处理的数据流仍在占用连接
内容的提问来源于stack exchange,提问作者asafJortillles
相关产品推荐
相关产品推荐

