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

原文地址:https://www.cnblogs.com/yalong/p/15601391.html