简体   繁体   English

当工作重叠时,spring @scheduled cron 的预期行为是什么?

[英]What is the expected behaviour of spring @scheduled cron when jobs would overlap?

I have a job that runs once an hour, and I'm using Spring's @scheduled cron to schedule it.我有一个每小时运行一次的工作,我正在使用 Spring 的 @scheduled cron 来安排它。

If the job takes more than an hour, I understand from How to prevent overlapping schedules in Spring?如果作业需要一个多小时,我从如何防止 Spring 中的日程重叠? that the next job won't kick off while the first job is running.当第一个工作正在运行时,下一个工作不会开始。

But does this mean that it WILL kick off after the first job has completed, or has it missed its chance?但这是否意味着它会在第一份工作完成后开始,还是错过了机会?

If I have one job that takes 10 hours, will all the missed cron jobs queue up and then execute one by one when the first job completes after 10 hours, or will just the first job run?如果我有一个需要 10 个小时的作业,那么所有错过的 cron 作业是否会排队,然后在第一个作业在 10 个小时后完成时一个一个执行,还是只运行第一个作业?

Thanks!谢谢!

By default, execution is blocking and single-threaded, which means they will not run concurrently.默认情况下,执行是阻塞和单线程的,这意味着它们不会并发运行。 If you want jobs to run simultaneously, you can annotate the method as @Async as well.如果您希望作业同时运行,您也可以将该方法注释为@Async You may also want to look at the different Executors .您可能还想查看不同的Executors

If you're using fixedDelay like in the sample question you provided, the next job will only kick off AFTER the current one is over, plus the delay.如果您在提供的示例问题中使用fixedDelay ,则下一项工作只会在当前工作结束后开始,加上延迟。 So if your job takes 10 hours and you have a fixedDelay of 5000 , the next job will kick off 5 seconds after the 10 hour one.因此,如果您的工作需要 10 个小时并且您的fixedDelay5000 ,则下一个工作将在 10 小时后的 5 秒开始。

If you're using fixedRate then the next scheduled event will be queued up to run, but not skipped, as per the documentation :如果您使用的是fixedRate那么下一个预定事件将排队等待运行,但不会被跳过,根据文档

If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.如果此任务的任何执行时间超过其周期,则后续执行可能会延迟开始,但不会并发执行。

If you are simply using cron , then the jobs will be queued and executed in turn (similar to fixedRate ).如果您只是使用cron ,那么作业将依次排队和执行(类似于fixedRate )。 You can test this with a simple method (below is in Groovy, but can use plain Java too):你可以用一个简单的方法来测试这个(下面是在 Groovy 中,但也可以使用普通的 Java):

    int i = 0

    @Scheduled(cron = '* * * * * * ')
    void test() {
        if (i < 5)
            Thread.sleep(10000)

        i += 1
        println '------------------------' + i // No values skipped
    }

You'll note that every number is printed;你会注意到每个数字都被打印出来了; eg no cycle is ever skipped.例如,不会跳过任何循环。

The behaviour of fixedRate and cron is different. fixedRatecron的行为是不同的。

Overlapping jobs are queued for fixedRate (as per the above answer from @Igor).重叠的作业排队等待fixedRate (根据@Igor 的上述答案)。

Overlapping jobs are skipped for cron . cron会跳过重叠的作业。

Sample Java code to demonstrate the difference:演示差异的示例 Java 代码:

int i = 0;
@Scheduled(fixedRate = 5000)
public void test() throws InterruptedException {
    Date start = new Date();
    if (i < 3) Thread.sleep(10000);
    i++;
    System.out.printf("start %TT, finish %TT, i = %s%n", start, new Date(), i);
}

And the output:和输出:

start 13:25:30, finish 13:25:40, i = 1
start 13:25:40, finish 13:25:50, i = 2
start 13:25:50, finish 13:26:00, i = 3
start 13:26:00, finish 13:26:00, i = 4
start 13:26:00, finish 13:26:00, i = 5
start 13:26:00, finish 13:26:00, i = 6
start 13:26:00, finish 13:26:00, i = 7
start 13:26:05, finish 13:26:05, i = 8
start 13:26:10, finish 13:26:10, i = 9
start 13:26:15, finish 13:26:15, i = 10

As can be seen, the overlapping jobs are queued and start as soon as the previous one completes, with no 5 second gap.可以看出,重叠的作业排队并在前一个完成后立即开始,没有 5 秒的间隔。

However, if we use @Scheduled(cron = "*/5 * * ? * *") instead, the output becomes:但是,如果我们使用@Scheduled(cron = "*/5 * * ? * *")代替,输出变为:

start 13:22:10, finish 13:22:20, i = 1
start 13:22:25, finish 13:22:35, i = 2
start 13:22:40, finish 13:22:50, i = 3
start 13:22:55, finish 13:22:55, i = 4
start 13:23:00, finish 13:23:00, i = 5
start 13:23:05, finish 13:23:05, i = 6
start 13:23:10, finish 13:23:10, i = 7
start 13:23:15, finish 13:23:15, i = 8
start 13:23:20, finish 13:23:20, i = 9
start 13:23:25, finish 13:23:25, i = 10

There is always a 5 second gap between the jobs.作业之间总是有 5 秒的间隔。 The overlapping jobs are NOT queued and are skipped.重叠的作业不会排队并被跳过。

Overlapping jobs are queued for fixedRate and they are skipped for cron as mentioned by @firstmanonmars正如@firstmanonmars 所提到的,重叠作业排队等待fixedRate并跳过cron

If we want to execute the corn schedulers overlapping to each other without waiting, we can use @Async and @EnableAsync as shown below.如果我们想在不等待的情况下执行相互重叠的玉米调度程序,我们可以使用@Async@EnableAsync ,如下所示。

@EnableScheduling
@SpringBootApplication
@EnableAsync

public class TaskSchedulerApplication {

    public static void main(String[] args) {
        SpringApplication.run(TaskSchedulerApplication.class, args);
    }
    
    @Bean
    public TaskScheduler taskScheduler() {
        final ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(10);
        return scheduler;
    }
}

Scheduler Demo:调度器演示:

@Component
public class DemoScheduler {
    
    @Async
    @Scheduled(cron = "*/5 * * * * MON-FRI")
    public void startJob() {
        System.out.println(String.format("%s - Thread name - %s ",new Date(), Thread.currentThread().getName()));
        sleep(6000);
    }

    private void sleep(int millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Running the code gives the following output which shows that they are running by multiple threads in parallel in an interval of 5 sec:运行代码给出以下输出,表明它们由多个线程以 5 秒的间隔并行运行:

Thu May 06 09:59:05 IST 2021 - Thread name - task-1 
Thu May 06 09:59:10 IST 2021 - Thread name - task-2 
Thu May 06 09:59:15 IST 2021 - Thread name - task-3 
Thu May 06 09:59:20 IST 2021 - Thread name - task-4 
Thu May 06 09:59:25 IST 2021 - Thread name - task-5 
Thu May 06 09:59:30 IST 2021 - Thread name - task-6 
Thu May 06 09:59:35 IST 2021 - Thread name - task-7 
Thu May 06 09:59:40 IST 2021 - Thread name - task-8 
Thu May 06 09:59:45 IST 2021 - Thread name - task-1 
Thu May 06 09:59:50 IST 2021 - Thread name - task-2 
Thu May 06 09:59:55 IST 2021 - Thread name - task-3

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

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