node项目在pm2 cluster模式下定时任务重复执行的问题
原文链接: https://www.cnblogs.com/yalong/p/15601391.html
背景:
有个需求,需要每天删除过期的数据,所以用到了定时任务,但是发现定时任务每次都是执行多次,原来是pm2 的 cluster模式导致的,最终还是解决了,在此记录
一. 定时任务怎么写
使用 node-schedule
, githuib地址是: https://github.com/node-schedule/node-schedule
node-schedule
更多使用可以参考这个https://www.cnblogs.com/zhongweiv/p/node_schedule.html
我的项目是koa2,这里以每3秒打印为例,具体使用就是在app.js 中添加如下代码
const schedule = require("node-schedule");
const job = schedule.scheduleJob("*/3 * * * * *", function () {
console.log('每3秒我执行一次,啦啦啦' + new Date())
});
如下图:
二.复现问题
1.使用pm2 的 cluster模式启动服务
我的pm2 的配置文件,pm2.josn 内容如下:
{
"apps": [
{
"name": "koa-test",
"script": "bin/www",
"cwd": "",
"exec_mode": "cluster",
"instances": 0,
"autorestart": true,
"node_args": [],
"args": [],
"env": {
"NODE_ENV": "production"
}
}
]
}
执行 pm2 start ./pm2.json
启动服务,如下图
执行pm2 log
查看打印日志,如下图
可以看到,每3秒后,一下子打印8次,就是说定时任务是重复执行的
三.解决问题
如下图
可以看到 pm2 实例的id是不重复的, 那么在某个指定id下执行定时任务不就ok了
这个id的属性获取方式是 process.env.NODE_APP_INSTANCE
在项目中测试
const job = schedule.scheduleJob("*/3 * * * * *", function () {
console.log(process.env.NODE_APP_INSTANCE)
});
再查看pm2 log
就能看到打印的就是pm2 中每个 worker 的id值
最终代码如下:
const job = schedule.scheduleJob("*/3 * * * * *", function () {
if (process.env.NODE_APP_INSTANCE === '0') {
console.log('每3秒我执行一次,啦啦啦' + new Date())
}
});
结果如下图所示,问题得以解决
分析总结
定时任务重复执行的原因是pm2 的cluster 模式创建的每个worker进程,是同步执行的,所以就导致了重复执行,
Node.js—Cluster多进程模式与PM2的实现可以参考这里: https://www.cnblogs.com/xingchong/p/13183162.html