MongoServerClosedError报错:MongoDB查询时提示服务器已关闭
解决MongoServerClosedError: Server is closed问题
错误原因
- 路由处理函数未等待异步的
getData()执行完成,直接将Promise对象传给response.send(),导致数据遍历过程中请求上下文异常,触发连接关闭。 - 每次请求都创建并关闭MongoClient连接,不符合最佳实践,频繁的连接销毁/重建容易引发服务器连接状态异常。
解决方法
方法1:修正路由的异步处理逻辑
将路由处理函数改为异步函数,等待getData()执行完成后再返回结果:
const uri = "uri"; // 替换为实际连接字符串 const client = new MongoDB.MongoClient(uri); app.get("/api", async (request, response) => { async function getData() { let result = []; try { await client.connect(); const db = client.db("myDatabase"); const collection = db.collection("myCollection"); const cursor = collection.find({}); for await (const item of cursor) { result.push(item); } } catch (e) { console.error("获取数据失败:", e); response.status(500).send("获取数据失败"); return []; } finally { await client.close(); } return result; }; const data = await getData(); response.send(data); });
方法2:复用MongoClient连接(推荐)
官方推荐复用MongoClient实例,在应用启动时建立一次连接,关闭时再断开,避免频繁连接开销:
const uri = "uri"; // 替换为实际连接字符串 const client = new MongoDB.MongoClient(uri); // 应用启动时初始化数据库连接 async function initDB() { try { await client.connect(); console.log("成功连接MongoDB"); } catch (err) { console.error("MongoDB连接失败:", err); process.exit(1); } } initDB(); app.get("/api", async (request, response) => { try { const db = client.db("myDatabase"); const collection = db.collection("myCollection"); // 直接用toArray()替代手动遍历,更简洁高效 const result = await collection.find({}).toArray(); response.send(result); } catch (err) { console.error("获取数据失败:", err); response.status(500).send("获取数据失败"); } }); // 应用退出时关闭数据库连接 process.on("SIGINT", async () => { await client.close(); console.log("MongoDB连接已断开"); process.exit(0); });
额外优化点
- 使用
collection.find({}).toArray()可以直接获取所有文档组成的数组,无需手动通过for await...of遍历收集结果,代码更简洁且性能更优。 - 全局复用MongoClient实例能大幅提升应用性能,避免频繁建立TCP连接的开销。
内容的提问来源于stack exchange,提问作者ICantCode
相关产品推荐
相关产品推荐

