Skip to main content

Distributed Scheduling 任务调度

1. Intro 简介

Scheduling is the process of executing a piece of logic at a specific time in the future. Scheduled jobs are a piece of business logic that should run on a timer. 调度是在未来的特定时间执行一段逻辑的过程。调度作业是一段应该在计时器上运行的业务逻辑。

2. @Scheduled 非分布式调度

Spring allows us to run scheduled jobs in the Spring container by using some simple annotations. The @Scheduled annotation is used to mark a method as a scheduled job. Spring 允许我们通过使用一些简单的注释在 Spring 容器中运行计划的作业。 @Scheduled 注释用于将方法标记为计划作业。

Scheduling is not enabled by default. Before adding any scheduled jobs we need to enable scheduling explicitly by adding the @enableScheduling annotation. 默认情况下不启用计划。在添加任何计划的作业之前,我们需要通过添加 @enableScheduling 注释来显式启用计划。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class JobschedulingApplication {

public static void main(String[] args) {
SpringApplication.run(JobschedulingApplication.class, args);
}

}

2.1 使用 Cron 表达式

Cron源自Unix/Linux系统自带的crond守护进程,以一个简洁的表达式定义任务触发时间。在Spring中,也可以使用Cron表达式来执行Cron任务,在Spring中,它的格式是:

秒 分 小时 天 月份 星期 年

年是可以忽略的,通常不写。每天凌晨2:15执行的Cron表达式就是:

0 15 2 * * *

每个工作日12:00执行的Cron表达式就是:

0 0 12 * * MON-FRI

每个月1号,2号,3号和10号12:00执行的Cron表达式就是:

0 0 12 1-3,10 * *

2.2 使用其他 @Scheduled Annotation

// initialDelay 延迟启动
// fixedDelay 固定延迟,时间间隔是前次任务的结束到下次任务的开始
// fixedRate 时间间隔是前次任务和下次任务的开始
@Scheduled(fixedDelay = 3000, initialDelay = 5000)
public void process() throws InterruptedException {
log.info("process....start");
Thread.sleep(2000);
log.info("process....stop");
}

2.3 @Scheduled 与多线程

修改 Spring 启动类,增加线程池配置

@SpringBootApplication
@EnableScheduling
@EnableAsync
public class DistributedJobApplication {

public static void main(String[] args) {
SpringApplication.run(DistributedJobApplication.class, args);
}

@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(10);
return taskScheduler;
}
}

模拟多线程任务调度

@Scheduled(fixedRate = 3000)
public void process1() throws InterruptedException {
log.info("process1...start");
Thread.sleep(50000);
log.info("process1...stop");
}

@Scheduled(fixedRate = 3000)
public void process2() throws InterruptedException {
log.info("process2...start");
Thread.sleep(50000);
log.info("process2...stop");
}

2023-02-14 00:30:19.477 INFO 21221 --- [taskScheduler-1] com.imooc.distributedjob.MyJob : process1...start
2023-02-14 00:30:19.477 INFO 21221 --- [taskScheduler-2] com.imooc.distributedjob.MyJob : process2...start

2023-02-14 00:30:24.477 INFO 21221 --- [taskScheduler-1] com.imooc.distributedjob.MyJob : process1...stop
2023-02-14 00:30:24.477 INFO 21221 --- [taskScheduler-2] com.imooc.distributedjob.MyJob : process2...stop