node.js 中的 Cronjobs

Posted

技术标签:

【中文标题】node.js 中的 Cronjobs【英文标题】:Cronjobs in node.js 【发布时间】:2011-08-03 21:51:08 【问题描述】:

是否可以在 node.js 中的特定时间定期调用函数?我的第一个实现是

setInterval(functionName(),(24*60*60*1000));

这是次优的,因为每次我重新启动节点时它都会重新启动。是否有更好的可能性来实现这一点?

【问题讨论】:

使用node-cron。 @MathiasBynens node-cron 对重启有什么抵抗力?抱歉,我是死灵法师,但这个 Q 仍然是谷歌搜索结果中的第一个。请注意,node-cron 不是基于 crontables。 @meeDamian node-cron 主要以间隔运行脚本,因此它们将在重新启动时再次开始循环。还有一个选项可以运行一次作业by date,这是一个可能来自持久数据源的值。 【参考方案1】:

这是一个老问题,但除了公认的答案之外,还值得一提的是带有示例的库。

cron 是一个轻量级的包,它以给定的时间间隔运行指定的函数,只使用系统时间,没有数据库持久性。

const CronJob = require('cron').CronJob;
const jobFiveMinutes = require("./job.five-minutes");
const jobMondayMorning = require("./job.monday-morning");

var jobs = [
    new CronJob(
        cronTime: "00 */5 * * * *", //every five minutes
        onTick: function() 
            jobFiveMinutes();
        ,
        start: false, //don't start immediately
        timeZone: 'America/Los_Angeles'
    ),
    new CronJob(
        cronTime: "00 00 9 * * 1", //9 am Monday morning
        onTick: function() 
            jobMondayMorning();
        ,
        start: false,
        timeZone: 'America/Los_Angeles'
    ),
];

jobs.forEach(function(job) 
    job.start(); //start the jobs
);

在上面,我们需要两个文件并在两个 cronjobs 中调用它们,设置不同的时间间隔。这些文件只是导出函数:

//job.five-minutes.js
module.exports = function()
    console.log("runs every five minutes")
;

//job.monday-morning.js
module.exports = function()
    console.log("runs every monday morning at 9 am, Los Angeles time")
;

无论您是在本地运行还是在任何区域的远程服务器上运行,它都会根据传递的时区运行(虽然这是可选的,在分钟的情况下无关紧要)。

此外,重新启动服务器/脚本不会影响其工作,因为它与系统时间同步。 "00 */5 * * * *" 作业将在 5 的每个倍数上运行,即 5、10、15、20 等等。因此,即使您在 24 点重新启动脚本,它也会在 25 点而不是 29 点运行。

最后,该软件包扩展了 cron 语法以在最左侧包含秒数。因此,您甚至可以知道您想要运行该作业的确切时间。

【讨论】:

【参考方案2】:

为了防止重新启动,您需要创建一个持久的数据存储作业。

类似:

Job = 
    _id: Number,
    job: String,
    dueDate: Date,
    completed: Boolean

然后有一些代码如下:

var createJob = function(url, date) 
    var j = db.create(Job, function(j) 
         j.job = url;
         j.dueDate = date;
         j.save();
    );
;

var runJob = function(j) 
    var id = j._id;
    setInterval(j.dueDate - Date.now(), function() 
         db.getOne(Job,  _id : id , function(j) 
             require(j.job);
             j.finished = true;
             j.save();  
         );
    );
    j = null;
;

在启动时,您只需执行以下操作:

db.get(Job,  finished: false , function(jobs) 
    jobs.forEach(runJob);
);

用 MongoDB、CouchDB、Redis 等替换通用的 db

【讨论】:

假设有多个 cron 作业正在运行,有没有办法简单地杀死其中一个?因为我遇到了一个场景,我需要终止一项工作并进行一些其他维护,但我仍然希望其他工作能够运行。谢谢!

以上是关于node.js 中的 Cronjobs的主要内容,如果未能解决你的问题,请参考以下文章

node.js 项目中的 index.js 用于啥?

配置node.js中的express框架

node.js 中的空循环行为

Node.js权威指南 (10) - Node.js中的错误处理与断言处理

Node.js中的URL

jQuery 函数不适用于 node.js 中的 express.js 路由