Node.js 中如何运行定时(cron)任务?
在 Node.js 里跑 cron 定时任务:node-cron 安装与 schedule 用法、cron 表达式示例、setInterval 替代方案、进程常驻注意事项与 FAQ。
用 node-cron 库:npm install node-cron 后,cron.schedule("表达式", 函数) 注册任务即可,进程运行期间任务按点触发。 只需固定间隔的话,内置 setInterval 也能顶,但表达不了"每天凌晨"这类日历语义。
1. 安装
npm install node-cron
2. 完整示例:每天零点清理临时文件
const fs = require('fs');
const path = require('path');
const cron = require('node-cron');
const TMP_DIR = path.join(__dirname, 'tmp');
// 每天 00:00 执行
cron.schedule('0 0 * * *', () => {
fs.readdir(TMP_DIR, (err, files) => {
if (err) return console.error('读取目录失败:', err);
for (const file of files) {
fs.unlink(path.join(TMP_DIR, file), err => {
if (err) console.error('删除失败:', file, err);
});
}
console.log(`清理完成,共 ${files.length} 个文件`);
});
});
表达式是标准五字段(分 时 日 月 星期),node-cron 也支持六字段(首位为秒)。
3. 常用写法
cron.schedule('*/5 * * * *', task); // 每 5 分钟
cron.schedule('30 2 * * 1', task); // 每周一 2:30
cron.schedule('*/10 * * * * *', task); // 每 10 秒(六字段格式)
// 手动控制
const job = cron.schedule('0 * * * *', task, { scheduled: false });
job.start(); // 启动
job.stop(); // 停止
4. 注意事项
- 进程必须常驻:node-cron 是进程内调度器,进程退出任务就没了。生产环境用 PM2、systemd 或容器保活。
- 单实例才安全:多副本部署时每份进程都会触发,任务会重复执行——用分布式锁或让任务只跑在指定实例上。
- 时区:
cron.schedule('0 0 * * *', fn, { timezone: 'Asia/Shanghai' })显式指定,避免容器里默认 UTC 造成的"差 8 小时"。
观测云对照
Node 服务接入观测云后,定时任务的关键路径可以随应用一起被 APM 追踪,每次执行的耗时、异常一目了然;任务日志由 DataKit 统一采集,再配心跳式监控器——计划窗口内没有成功日志就告警,进程崩溃、事件循环阻塞导致任务跳过的场景都能被兜住。
常见问题(FAQ)
Q:node-cron 和系统 crontab 选哪个?
A:任务逻辑离不开 Node 代码(要 require 业务模块)用 node-cron;任务本身是独立脚本、运维要统一管理调度,用系统 crontab 调 node script.js。
Q:进程重启会错过执行吗?
A:会,node-cron 不做错过补偿(misfire)。关键任务启动时先检查"上次执行时间",落后太久就立即补跑一次。
Q:能动态修改调度吗?
A:不能改已有任务的表达式,但可以 job.stop() 后用新表达式重新 schedule。