十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Mongoose 查询报 Operation timed out after 10000 ms 怎么排查?

Mongoose 查询报 Operation timed out after 10000 ms 怎么排查? Mongoose 查询报 Operation timed out after 10000 ms 怎么排查【免费下载链接】mongooseMongoDB object modeling designed to work in an asynchronous environment.项目地址: https://gitcode.com/GitHub_Trending/mo/mongoose当你的 Mongoose 查询如findOne()、find()挂起约 10 秒后抛出类似Operation ...() buffering timed out after 10000ms的错误时问题的核心通常只有一个Mongoose 还没有连上 MongoDB。Mongoose 默认开启操作缓冲buffering模型上的所有方法调用会被放进队列等到连接建立后再执行如果队列中的操作等待超过bufferTimeoutMS默认 10000即 10 秒Mongoose 就会抛出这个超时错误见 docs/faq.md 与 lib/drivers/node-mongodb-native/collection.js。换句话说这个报错本身不是查询太慢而是连接没建立起来查询一直在排队。下面按 docs/faq.md 和 docs/connections.md 给出的线索排查。第一步确认连接是否真正建立这是 FAQ 中明确给出的首要原因。Mongoose 允许你在连接之前就开始使用模型且默认不报错所以很容易在没连上数据库的情况下发起查询。FAQ 列举了两类典型写法示例中的mongodbUri、schema是占位符需替换为你自己的连接字符串和 schema// 错误示例 1createConnection() 传了 URI 但没有 await // 等连接完成模型注册在默认连接上而默认连接从未 connect await mongoose.createConnection(mongodbUri).asPromise(); const Test mongoose.model(Test, schema); await Test.findOne(); // 因为没调用 mongoose.connect()抛 Operation timed out// 错误示例 2createConnection() 没有传 URI // db 连接从未建立 await mongoose.connect(mongodbUri); const db mongoose.createConnection(); const Test db.model(Test, schema); await Test.findOne(); // db 未连接 MongoDB抛 Operation timed out正确的主路径是显式等待连接完成await mongoose.connect(mongodb://127.0.0.1:27017/myapp);docs/connections.md 建议本地连接使用127.0.0.1而不是localhostNode.js 18 及以上优先使用 IPv6localhost可能被解析为::1而 MongoDB 默认不接受 IPv6 连接。如果你看到的是connect ECONNREFUSED ::1:27017按 FAQ 的说明把主机换成127.0.0.1即可。第二步让错误更快暴露确认连接状态排查缓冲类问题docs/connections.md 的 Operation Buffering 一节给出的建议是先关掉bufferCommands看连接是不是根本没打开因为它能消除调用被静默排队这层伪装// 全局关闭缓冲未连接时的操作会立即报错而不是排队等 10 秒 mongoose.set(bufferCommands, false);也可以缩短缓冲超时让错误在 500ms 而不是 10s 后出现加快定位// 操作在缓冲中超过 500ms 就抛错 mongoose.set(bufferTimeoutMS, 500);同时开启 debug 输出和连接事件监听直接观察连接走到哪一步均出自 docs/faq.md 与 docs/connections.mdmongoose.set(debug, true); // 所有执行的方法输出日志 mongoose.connection.on(connected, () console.log(connected)); mongoose.connection.on(disconnected, () console.log(disconnected)); mongoose.connection.on(error, err console.log(error, err));判断依据如果启动后一直没打印connected说明连接本身没建立继续查 URI 与网络如果打印过connected又出现disconnected说明连接建立后丢失——注意文档提醒Mongoose 丢失连接时不一定触发error事件应以disconnected为准。另外两个容易混淆的超时错误属于不同机制排查方向不同见 docs/connections.md 的 Server Selection 一节MongoTimeoutError: Server selection timed out after 30000 ms这是 MongoDB 驱动的服务端选择超时由serverSelectionTimeoutMS控制默认 30000ms覆盖mongoose.connect()和所有发往 MongoDB 的操作。错误对象带reason属性会说明具体原因比如密码错误时reason中包含 Authentication failed。连接复制集时出现MongooseServerSelectionError: connect ECONNREFUSED localhost:27017文档建议连接err.reason.servers查看驱动认为的复制集成员状态如果成员主机名是localhost需要用 mongo shell 的rs.conf()检查并修改成员主机名。针对 AtlasFAQ 还给出两条相关线索连不上远程集群时确认当前 IP 已在 Atlas 的 IP 白名单中可用0.0.0.0/0放开使用mongodbsrv://出现querySrv ECONNREFUSED时可在入口文件最顶部其他 import 之前设置 DNS 服务器再连接。第三步修复连接验证结果修复方式就是让连接在查询之前真正建立例如try { await mongoose.connect(mongodb://127.0.0.1:27017/myapp); } catch (error) { // 初始连接失败不会自动重连必须在这里处理 console.error(error); }验证是否解决connected事件打印或mongoose.connect()的 promise 成功 resolve之前超时的查询改为正常返回结果不再出现buffering timed out。文档还明确了初始连接失败后 Mongoose不会自动重连只有建立过连接后的错误才会触发自动重连所以启动阶段必须用catch/try/catch处理connect()的失败。限制与注意事项关闭bufferCommands后依赖缓冲的autoCreate机制建集合也不会再等待连接如果你用了autoCreate文档要求同时关掉它改用Model.createCollection()显式建集合。bufferTimeoutMS、serverSelectionTimeoutMS、socketTimeoutMS是三个不同层级的超时分别对应 Mongoose 缓冲队列、驱动的服务端选择重试、连接建立后 socket 的空闲超时不要把它们的数值互相套用。连接应随应用启动打开、随应用关闭关闭不要为每次数据库操作创建新连接FAQShould I create/destroy a new connection for each database operation?。更多背景可查阅 docs/faq.md 的 Operation...timed out after 10000 ms 与 Mysave()operation never completes 两节以及 docs/connections.md 的 Buffering、Error Handling、Server Selection 章节。【免费下载链接】mongooseMongoDB object modeling designed to work in an asynchronous environment.项目地址: https://gitcode.com/GitHub_Trending/mo/mongoose创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表