Node.js进程处理大量记录后挂起问题求助
问题分析与解决方案
你的Node.js进程在处理MongoDB交易记录游标时挂起,排除内存不足因素后,可从以下几个方向排查解决:
1. 移除高频同步控制台输出
console.log是同步IO操作,Windows环境下控制台输出效率极低,高频调用会阻塞事件循环,导致进程假死。修改为批量输出或暂时注释:
// 替换原console.log,每1000条输出一次 if (processTxns % 1000 === 0) { console.log(`Process Txns: ${processTxns}`); }
2. 调整MongoDB游标批次配置
默认游标批次大小为101条,频繁的网络交互可能导致游标获取阻塞。手动设置更大的批次:
const transactionCursor = target_db.collection("transaction").find().batchSize(1000);
3. 替换for await...of为手动游标迭代
部分MongoDB驱动版本对for await...of的游标迭代存在兼容性问题,改用next()手动控制循环并添加错误捕获:
async function processTransactions() { processTxns = 0; const transactionObj = {}; const transactionCursor = target_db.collection("transaction").find().batchSize(1000); let transactionDoc; try { while ((transactionDoc = await transactionCursor.next())) { processTxns++; if (transactionDoc.orderId && transactionDoc.orderId[0]) { const orderIdString = String(transactionDoc.orderId[0].oid); if (!orderIdString) continue; const existingDoc = transactionObj[orderIdString]; if (!existingDoc || existingDoc._id < transactionDoc._id) { transactionObj[orderIdString] = transactionDoc; } } if (processTxns % 1000 === 0) { console.log(`Process Txns: ${processTxns}`); } } } catch (err) { console.error("Cursor iteration failed:", err); } finally { await transactionCursor.close(); } } processTransactions();
4. 避免存储完整文档,只保留必要字段
完整的MongoDB文档可能包含BSON特殊类型或循环引用,增加内存开销的同时可能导致隐性阻塞。仅存储需要的字段:
// 替换原存储逻辑,只保留关键字段 transactionObj[orderIdString] = { _id: transactionDoc._id, orderId: transactionDoc.orderId, // 其他业务必须字段 };
5. 升级MongoDB驱动版本
旧版本驱动可能存在游标迭代的bug,升级至最新稳定版:
npm install mongodb@latest
内容的提问来源于stack exchange,提问作者Shekhar
相关产品推荐
相关产品推荐

