欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring Boot应用中进行任务调度

程序员文章站 2022-05-01 19:22:19
...

Spring Boot(十五)— 任务调度

任务调度(也可以称为定时任务)是指在特定的时间段去执行一个规定的任务过程。Spring Boot为开发者提供了一个更优雅的方式创建任务调度程序。在本章节中,我们将学习使用Spring Boot来创建任务调度程序。

任务调度分为两种类型,一种是间隔时间执行的任务,如每隔3秒执行一次任务程序;另外一种时指定具体时间的任务,如在每天的凌晨整点备份数据库。

Cron表达式

在开始讲解定时任务之前,先来看一下定时任务中的Cron表达式的相关内容。Cron表达式用于配置CronTrigger实例,它是org.quartz.Trigger的子类。Cron表达式被放置在**@Scheduled** 注释标签中,下面的代码给出了一个cron表达式的样例:

@Scheduled(cron = "0/5 * 22 * * ?")
public void cronJobSchedule(){
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    Date now = new Date();
    logger.info("Java cron job expression scheduler::"+sdf.format(now));
}
复制代码

在cron表达式中,一共有七位表达式参数,我们将使用一张表格来了解各个参数的用途:

位数 说明 范围
第一位 表示秒 取值范围:0-59
第二位 表示分钟 取值范围:0-59
第三位 表示小时 取值范围:0-23
第四位 表示日期 取值范围:1-31
第五位 表示月份 取值范围:1-12
第六位 表示星期 取值范围:1-7
第七位 表示年份,通常置空 取值范围:1970-2099

说明,在第六位星期参数中,1表示的是星期日,除使用数字表示外,还可以使用表示星期的英文缩写来设置

了解了cron表达式的语法规则后,我们再来了解一下表达式中各种占位符的含义。cron表达式中一共可以使用的占位符有5个,如下表所示:

占位符 说明 示例
(星号)* 可以理解为一个周期 每秒、没分、每小时等
(问好)? 只能出现在日期和星期两个位置中 表示时间不确定
(横线)- 表示一个时间范围 如在小时中10-11,表示从上午10点到上午11点
(逗号), 表示一个列表值 如在星期中使用:1,3,5 表示星期一、星期三和星期五
(斜杠)/ 表示一个开始时间和间隔时间周期 在分钟中使用:0/15 表示从0分开始,每15分钟运行一次

下面将列举一些示例来说明cron表达式和占位符:

表达式 说明
0 0 0 * * ? 每天00:00:00执行任务
0 30 10 * * ? 每天上午10:30:00执行任务
0 30 10 ? * * 每天上午10:30:00执行任务
0 0/15 10 * * ? 每天上午10:00:00、10:15:00、10:30:00和10:45:00这四个时间点执行任务
0 0 0 ? * 1 每个星期天的凌晨整点执行任务
0 0 0 ? * 1#3 每个月的第三个星期天的凌晨整点执行任务

开启定时任务

在Spring Boot应用程序中,需要使用**@EnableScheduling**注解来开启对定时任务的支持,并且该注解应该用于应用程序主类上,下面的代码演示了在Spring Boot中开启定时任务支持。

package com.ramostear.application;

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

@SpringBootApplication
@EnableScheduling
public class ScheduleApplication {

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

}

复制代码

固定时间任务

下面我们将使用cron表达式创建一个固定时间的调度任务来实现每天的22点到23点每隔15秒钟执行一次任务。

package com.ramostear.application.schedule;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author ramostear
 * @create-time 2019/3/11 0011-21:49
 * @modify by :
 * @since:
 */
@Component
public class DemoScheduler {

    private static final Logger logger = LoggerFactory.getLogger(DemoScheduler.class);

    @Scheduled(cron = "0/15 * 22-23 * * ?")
    public void cronJobSchedule(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        Date now = new Date();
        logger.info("Java cron job expression scheduler::"+sdf.format(now));
    }
}
复制代码

下面的文本是应用程序在23:09分启动后,控制台窗口输出的日志信息:

[2019-03-11T23:09:00.000z][com.ramostear.application.schedule.DemoScheduler][scheduling-1][26][INFO ] 
Java cron job expression scheduler::2019-03-11 23:09:00.001
[2019-03-11T23:09:15.015z][com.ramostear.application.schedule.DemoScheduler][scheduling-1][26][INFO ] 
Java cron job expression scheduler::2019-03-11 23:09:15.002
[2019-03-11T23:09:30.030z][com.ramostear.application.schedule.DemoScheduler][scheduling-1][26][INFO ] 
Java cron job expression scheduler::2019-03-11 23:09:30.001
[2019-03-11T23:09:45.045z][com.ramostear.application.schedule.DemoScheduler][scheduling-1][26][INFO ] 
Java cron job expression scheduler::2019-03-11 23:09:45.002
[2019-03-11T23:10:00.000z][com.ramostear.application.schedule.DemoScheduler][scheduling-1][26][INFO ] 
Java cron job expression scheduler::2019-03-11 23:10:00.002
复制代码

固定周期任务

固定时间周期调度任务是指从应用程序启动开始,在固定的时间周期执行一次任务,如每1000毫秒执行一次、每1分钟执行一次。下面的代码给出了创建固定周期调度任务的示例:

@Scheduled(fixedRate = 1000)
public void fiexdRateSchedule(){
    //TODO ...
}
复制代码

通过配置fixedRate参数的值,实现从应用程序启动后,每隔5秒钟执行一次任务。

package com.ramostear.application.schedule;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author ramostear
 * @create-time 2019/3/11 0011-21:49
 * @modify by :
 * @since:
 */
@Component
public class DemoScheduler {

    private static final Logger logger = LoggerFactory.getLogger(DemoScheduler.class);

    @Scheduled(fixedRate=5000)
    public void fixedRateSchedule(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        Date now = new Date();
        logger.info("Java fixedRate scheduler::"+sdf.format(now));
    }
}
复制代码

下面的文本是在23:18分启动应用程序后,控制台窗口输出的日志信息。

[2019-03-11T23:18:22.022z][com.ramostear.application.schedule.DemoScheduler][scheduling-1][33][INFO ] 
Java fixedRate scheduler::2019-03-11 23:18:22.062
[2019-03-11T23:18:27.027z][com.ramostear.application.schedule.DemoScheduler][scheduling-1][33][INFO ] 
Java fixedRate scheduler::2019-03-11 23:18:27.062
[2019-03-11T23:18:32.032z][com.ramostear.application.schedule.DemoScheduler][scheduling-1][33][INFO ] 
Java fixedRate scheduler::2019-03-11 23:18:32.062
[2019-03-11T23:18:37.037z][com.ramostear.application.schedule.DemoScheduler][scheduling-1][33][INFO ] 
Java fixedRate scheduler::2019-03-11 23:18:37.063
[2019-03-11T23:18:42.042z][com.ramostear.application.schedule.DemoScheduler][scheduling-1][33][INFO ] 
Java fixedRate scheduler::2019-03-11 23:18:42.062
复制代码

时延调度

所谓的时延调度,是通过设置initialDelayfixedDelay属性的值来控制当应用程序启动成功后,推迟一定时间再执行调度任务,其使用的语法如下:

@Scheduled(fixedDelay=1000,initialDelay=1000)
public fixedDelaySchedule(){
    
}
复制代码

现在,我们将实现一个特定的定时任务需求:在应用程序启动成功后延迟10秒钟,再以每5秒钟的频率执行任务:

package com.ramostear.application.schedule;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author ramostear
 * @create-time 2019/3/11 0011-21:49
 * @modify by :
 * @since:
 */
@Component
public class DemoScheduler {

    private static final Logger logger = LoggerFactory.getLogger(DemoScheduler.class);

    @Scheduled(fixedDelay = 5000,initialDelay = 10000)
    public void fixedRateAndInitialDelaySchedule(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        Date now = new Date();
        logger.info("Java fixedRate and initialDelay scheduler::"+sdf.format(now));
    }
}

复制代码

下面的文本显示了在23:30:59启动应用程序,控制台窗口输出的日志信息:

[2019-03-11T23:31:01.001z][org.springframework.boot.StartupInfoLogger][main][59][INFO ] Started ScheduleApplication in 2.193 seconds (JVM running for 2.904)
[2019-03-11T23:31:11.011z][com.ramostear.application.schedule.DemoScheduler][scheduling-1][40][INFO ] Java fixedRate and initialDelay scheduler::2019-03-11 23:31:11.639
[2019-03-11T23:31:16.016z][com.ramostear.application.schedule.DemoScheduler][scheduling-1][40][INFO ] Java fixedRate and initialDelay scheduler::2019-03-11 23:31:16.640
[2019-03-11T23:31:21.021z][com.ramostear.application.schedule.DemoScheduler][scheduling-1][40][INFO ] Java fixedRate and initialDelay scheduler::2019-03-11 23:31:21.641
[2019-03-11T23:31:26.026z][com.ramostear.application.schedule.DemoScheduler][scheduling-1][40][INFO ] Java fixedRate and initialDelay scheduler::2019-03-11 23:31:26.643
[2019-03-11T23:31:31.031z][com.ramostear.application.schedule.DemoScheduler][scheduling-1][40][INFO ] Java fixedRate and initialDelay scheduler::2019-03-11 23:31:31.644
复制代码

从日志信息中可以看到,应用程序在23:31:01启动成功。等待十秒后,在23:31:11输出了第一条日志信息,往后每隔5秒输出一条日志信息。

注意:上面所设置的参数都是以毫秒为单位

本章节的课程源码已经上传至Github代码仓库,你可以访问下面的链接获取课程源码:github.com/ramostear/s…

原文:Spring Boot应用中进行任务调度

转载于:https://juejin.im/post/5ca5ac616fb9a05e247af93c