Node.js worker-farm意外停止问题排查求助
Worker-farm 任务突然停止/变慢的问题排查与解决
你的问题核心是任务提交速度远超worker处理能力,导致任务队列无限积压,内存耗尽后进程逐渐变慢直至终止。下面是具体的解决思路:
1. 立刻停止用setInterval(0)提交任务
setInterval(0)会以Node.js允许的最快速度(几毫秒一次)疯狂往worker池塞任务,而worker的处理能力是有限的(默认等于CPU核心数)。短时间内队列就会堆积成天文数字,内存被占满后,进程自然会卡顿、崩溃。
替换成两种方式之一:
- 固定合理的间隔:比如根据任务处理耗时,设成
setInterval(..., 50)(具体数值自己测试,保证worker能跟上节奏) - 异步串行/批量提交:等一个任务完成后再提交下一个,或者一次提交N个,待这批处理完再继续,示例代码:
async function submitTasks() { while (true) { let randomNumber = config.generalInfo.itemList[Math.floor(Math.random() * config.generalInfo.itemList.length)]; let randomCookie = altCookies[Math.floor(Math.random() * altCookies.length)]; await new Promise((resolve, reject) => { workers(randomNumber, randomCookie, (err, result) => { if (err) { console.error('任务出错:', err); return reject(err); } let jsoned = JSON.parse(result); console.log(`${count++} ${jsoned.itemId} ${jsoned.price}`); resolve(); }); }); // 可选:加个小间隔避免太密集 await new Promise(resolve => setTimeout(resolve, 10)); } } submitTasks();
2. 配置worker-farm的并发参数
初始化worker时,明确限制并发数和每个worker的最大任务量,避免worker过载或内存泄漏:
const os = require('os'); const workerFarm = require('worker-farm'); const workers = workerFarm({ maxConcurrentWorkers: os.cpus().length, // 一般设为CPU核心数,也可根据需求调整 maxCallsPerWorker: 100, // 每个worker处理100个任务后重启,防止内存泄漏 maxConcurrentCallsPerWorker: 5 // 单个worker同时处理的任务数,避免单个worker过载 }, require.resolve('./你的worker脚本路径'));
3. 补上错误处理逻辑
你当前的代码完全没处理worker返回的err,如果某个任务出错导致worker卡住,会直接让队列里的后续任务排队等待,最终拖垮整个进程。必须加上错误处理:
workers(randomNumber, randomCookie, (err, result) => { if (err) { console.error('Worker执行出错:', err); // 可以在这里做重试或者跳过逻辑 return; } try { let jsoned = JSON.parse(result); console.log(`${count++} ${jsoned.itemId} ${jsoned.price}`); } catch (parseErr) { console.error('解析结果失败:', parseErr); } });
4. 监控任务队列状态
可以自己加个计数器监控待处理的任务数,当超过阈值时暂停提交:
let pendingTasks = 0; const MAX_PENDING = 100; // 设一个合理的阈值 function submitTask() { if (pendingTasks >= MAX_PENDING) { // 任务太多,等一会儿再提交 setTimeout(submitTask, 100); return; } pendingTasks++; let randomNumber = config.generalInfo.itemList[Math.floor(Math.random() * config.generalInfo.itemList.length)]; let randomCookie = altCookies[Math.floor(Math.random() * altCookies.length)]; workers(randomNumber, randomCookie, (err, result) => { pendingTasks--; if (err) { console.error('任务出错:', err); return; } // 原有处理逻辑 }); } // 用setInterval控制提交频率,比如每10ms提交一个 setInterval(submitTask, 10);
内容的提问来源于stack exchange,提问作者cooldevnocap
相关产品推荐
相关产品推荐

