实战Spring Boot 2.0系列(六) - 单机定时任务的几种实现

前言

定时任务 一般会存在 中大型企业级 项目中,为了减少 服务器数据库 的压力,往往会以 定时任务 的方式去完成某些业务逻辑。

常见的就是 金融服务系统 推送回调,一般支付系统订单在没有收到成功的回调返回内容时会 持续性的回调,这种回调一般都是 定时任务 来完成。

还有就是 报表的生成,我们一般会在客户 访问量小 时完成这个操作,也可以采用 定时任务 来完成。

正文

定时任务的几种方式

Timer

这是 Java 自带的 java.util.Timer 类,这个类允许调度一个名为 java.util.TimerTask 任务。使用这种方式可以让你的程序按照某一个 频度 执行,但不能在 指定时间 运行。现在一般用的较少。

ScheduledExecutorService

JDK 自带的一个类,是基于 线程池 设计的定时任务类,每个 调度任务 都会分配到 线程池 中的一个 线程 去执行。也就是说,任务是 并发执行,互不影响的。

Spring Task

Spring 3.0 以后自带的 Task,支持 多线程 调度,可以将它看成一个 轻量级Quartz,而且使用起来比 Quartz 简单许多,但是适用于 单节点定时任务调度

Quartz

这是一个 功能比较强大 的的调度器,可以让你的程序在指定时间执行,也可以按照某一个频度执行,配置起来 稍显复杂Quartz 功能强大,可以结合 数据库持久化,进行 分布式任务延时调度

Cron表达式简介

Cron 表达式是一个字符串,字符串以 56空格 隔开,分为 67,每一个域代表一个含义,Cron 有如下两种语法格式:

  1. Seconds Minutes Hours DayofMonth Month DayofWeek Year
  2. Seconds Minutes Hours DayofMonth Month DayofWeek

每个域对应的含义、域值范围和特殊表示符,从左到右依次如下:

字段 允许值 允许的特殊字符
0-59 , - * /
0-59 , - * /
小时 0-23 , - * /
日期 1-31 , - * / L W C
月份 1-12 或者 JAN-DEC , - * /
星期 1-7 或者 SUN-SAT , - * / L C #
年(可选) 留空, 1970-2099 , - * /

如上面的表达式所示:

  • “”字符: 被用来指定所有的值。如:在分钟的字段域里表示”每分钟”。

  • “-“字符: 被用来指定一个范围。如:”10-12” 在小时域意味着 “10点、11点、12点”。

  • “,”字符: 被用来指定另外的值。如:”MON,WED,FRI” 在星期域里表示 “星期一、星期三、星期五”。

  • “?”字符: 只在日期域和星期域中使用。它被用来指定”非明确的值”。当你需要通过在这两个域中的一个来指定一些东西的时候,它是有用的。看下面的例子你就会明白。

  • “L”字符: 指定在月或者星期中的某天(最后一天)。即 “Last” 的缩写。但是在星期和月中 “L” 表示不同的意思,如:在月子段中 “L” 指月份的最后一天 - 1月31日,2月28日。

    • 如果在星期字段中则简单的表示为 “7” 或者 “SAT” 字符。
    • 如果在星期字段中在某个 value 值得后面,则表示 “某月的最后一个星期value”,如 “6L” 表示某月的最后一个星期五。
  • “W”字符: 只能用在月份字段中,该字段指定了离指定日期最近的那个星期日。

  • “#”字符: 只能用在星期字段,该字段指定了第几个星期 value 在某月中

每一个元素都可以显式地规定一个值(如 6),一个区间(如 9-12),一个列表(如 9,11,13)或一个通配符(如 *)。“月份中的日期”“星期中的日期” 这两个元素是 互斥的,因此应该通过设置一个 问号?)来表明你不想设置的那个字段。下表显示了一些 cron 表达式的 例子 和它们的意义:

表达式 意义
“0 0 12 * * ?” 每天中午12点触发
“0 15 10 ? * *” 每天上午10:15触发
“0 15 10 * * ?” 每天上午10:15触发
“0 15 10 * * ? *” 每天上午10:15触发
“0 15 10 * * ? 2005” 2005年的每天上午10:15触发
“0 * 14 * * ?” 在每天下午2点到下午2:59期间的每1分钟触发
“0 0/5 14 * * ?” 在每天下午2点到下午2:55期间的每5分钟触发
“0 0/5 14,18 * * ?” 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
“0 0-5 14 * * ?” 在每天下午2点到下午2:05期间的每1分钟触发
“0 10,44 14 ? 3 WED” 每年三月的星期三的下午2:10和2:44触发
“0 15 10 ? * MON-FRI” 周一至周五的上午10:15触发
“0 15 10 15 * ?” 每月15日上午10:15触发
“0 15 10 L * ?” 每月最后一日的上午10:15触发
“0 15 10 ? * 6L” 每月的最后一个星期五上午10:15触发
“0 15 10 ? * 6L 2002-2005” 2002年至2005年的每月的最后一个星期五上午10:15触发
“0 15 10 ? * 6#3” 每月的第三个星期五上午10:15触发
0 6 * * * 每天早上6点
0 /2 * * 每两个小时
0 23-7/2,8 * * * 晚上11点到早上8点之间每两个小时,早上八点
0 11 4 * 1-3 每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点
0 4 1 1 * 1月1日早上4点

环境准备

配置gradle依赖

利用 Spring Initializer 创建一个 gradle 项目 spring-boot-scheduler-task-management,创建时添加相关依赖。得到的初始 build.gradle 如下:

buildscript {
    ext {
        springBootVersion = '2.0.3.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'io.ostenant.springboot.sample'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
    mavenCentral()
}


dependencies {
    compile('org.springframework.boot:spring-boot-starter')
    compile('org.springframework.boot:spring-boot-starter-web')
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

Spring Boot 入口类上配置 @EnableScheduling 注解开启 Spring 自带的定时处理功能。

@SpringBootApplication
@EnableScheduling
public class Application {
   
    public 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值