Cron任务中child_process未终止致内存暴涨的解决方法咨询
解决Node.js Cron任务中子进程无法终止的问题
问题描述
通过Cron每2分钟执行一次child_process.exec启动子进程,但子进程无法自动终止,导致服务器内存持续增长,需每小时强制重启。尝试直接调用exec.kill()无效,因为误将导入的exec函数当作子进程实例操作。
错误原因
你之前的代码中,exec是从child_process导入的执行函数,并非调用exec()后返回的ChildProcess实例,因此调用exec.kill()不会对任何子进程生效。
正确解决方案
核心是保存子进程实例,在每次Cron任务执行前检查并终止未结束的旧进程,同时给子进程设置超时防止无限运行:
完整修复代码
let { exec } = require("child_process"); let runningChildProcess = null; // 全局保存当前运行的子进程实例 const job = new cron.schedule("*/2 * * * *", function () { console.log("Cron job Twitter API started"); // 检查是否存在未结束的子进程,若有则终止 if (runningChildProcess && runningChildProcess.exitCode === null) { console.log("终止上一次运行的子进程..."); // 先发送优雅终止信号,允许子进程清理资源 runningChildProcess.kill('SIGTERM'); // 5秒后仍未结束则强制杀掉 setTimeout(() => { if (runningChildProcess.exitCode === null) { runningChildProcess.kill('SIGKILL'); console.log("强制终止未结束的子进程"); } }, 5000); } // 启动新子进程并保存实例 runningChildProcess = exec( "node /home/user/Raid/src/sub2/index.js", function (error, stdout, stderr) { if (error) { console.log(error.stack); console.log("错误代码: " + error.code); console.log("接收的信号: " + error.signal); } console.log("子进程STDOUT: " + stdout); console.log("子进程STDERR: " + stderr); // 子进程结束后清空实例 runningChildProcess = null; } ); // 设置子进程超时(110秒,小于2分钟的任务间隔) runningChildProcess.setTimeout(110000, () => { console.log("子进程超时,开始终止..."); runningChildProcess.kill('SIGTERM'); }); });
关键说明
- 保存子进程实例:用
runningChildProcess变量存储每次exec()返回的ChildProcess对象,用于后续的终止操作。 - 检查进程状态:通过
exitCode === null判断进程是否仍在运行(进程结束后会赋值exitCode)。 - 优雅终止+强制兜底:先发送
SIGTERM信号让子进程优雅退出,超时未结束则用SIGKILL强制终止。 - 设置超时机制:避免子进程因逻辑问题无限运行,确保即使Cron任务未触发,进程也会被自动终止。
内容的提问来源于stack exchange,提问作者JustinL
相关产品推荐
相关产品推荐

