简体   繁体   English

在 Node.js 服务器上间隔 24 小时安排多个 cron 作业

[英]Schedule multiple cron jobs 24h apart on Node.js server

I currently have 3 tasks that need to be executed every 3 days, and I want them to be staggered with 24h in between so that only one job runs on a given day for the following schedule:我目前有 3 个任务需要每 3 天执行一次,我希望它们之间 24 小时交错,以便在给定的一天只运行一个作业,如下时间表:

day1: job1第 1 天:作业 1

day2: job2第2天:工作2

day3: job3第3天:工作3

day4: job1第4天:工作1

day5: job2第5天:工作2

day6: job3 and so on第6天:job3等

Here is my current (clumsy) approach using 24h timeouts to stagger the jobs这是我目前使用 24 小时超时来错开工作的(笨拙的)方法

import cron from 'node-cron'

cron.schedule('0 0 12 */3 * *', () => {
  console.log('run job 1')
})
setTimeout(() => {  
    cron.schedule('0 0 12 */3 * *', () => {
        console.log('run job 2')
    })
    setTimeout(() => {  
        cron.schedule('0 0 12 */3 * *', () => {
            console.log('run job 3')
        }) 
    }, 24 * 3600 * 1000)
}, 24 * 3600 * 1000)

This seems very unstable and the timing gets screwed up every time the server gets interrupted or has to be restarted.这似乎非常不稳定,每次服务器中断或必须重新启动时,时间都会被搞砸。

Is there a way to tell cron the timing between multiple jobs so that they are automatically spaced 24h apart, and so that cron knows which job is supposed to run on any given calendar day?有没有办法告诉 cron 多个作业之间的时间安排,以便它们自动间隔 24 小时,以便 cron 知道在任何给定的日历日应该运行哪个作业?

If I were to do something like this, my approach would be as follows:如果我要做这样的事情,我的方法如下:

import cron from 'node-cron';

let currentJob = 0;

cron.schedule('0 0 12 * * *', () => {
  const jobs = [ job1, job2, job3 ];
  jobs[currentJob]();
  currentJob = (currentJob + 1) % 3;
});

This way, a new job is run each day.这样,每天都会运行一个新作业。

But this has an implication, whenever the server is restarted or interrupted, regardless of the last job that was run, the first task is run.但这有一个含义,每当服务器重新启动或中断时,无论最后运行的作业如何,都会运行第一个任务。 This is an undesired behaviour if the order in which the tasks are carried out matters, and I suspect it does.如果执行任务的顺序很重要,这是一种不受欢迎的行为,我怀疑确实如此。 You will then need to somehow persist the value currentJob so that it doesn't reset to zero.然后,您需要以某种方式保留currentJob值,以免它重置为零。 Something like this should suffice:这样的事情应该足够了:

import cron from 'node-cron';
import fs from "fs";

cron.schedule('0 0 12 * * *', () => {
  const jobs = [ job1, job2, job3 ];
  currentJob = getCurrentJobValue();
  jobs[currentJob]();
  setCurrentJobValue(currentJob + 1);
});

const FILE_NAME = "currentJob.json";

function getCurrentJobValue() {
    if (!fs.existsSync(FILE_NAME)) {
        fs.writeFileSync(FILE_NAME, JSON.stringify({
            currentJob: 0
        }));
        return 0;
    }
    let data = fs.readFileSync(FILE_NAME);
    return JSON.parse(data).currentJob;
}

function setCurrentJobValue(value) {
    var data = fs.readFileSync(FILE_NAME);
    fs.writeFileSync(FILE_NAME, JSON.stringify({
        currentJob: value % 3
    }));
    return value % 3;
}

This is a more robust solution as it covers the case of the server restarting.这是一个更强大的解决方案,因为它涵盖了服务器重新启动的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM