Spring Boot入坑-8-定时任务
-
在企业级的项目业务中,往往会有一系列的任务需要在有逻辑的指定时间点执行,如系统间定时同步数据、定时做某个复杂的计算、订单提交后30分钟需要付款等
-
上述这些,就需要任务的定时调度与执行来完成,这是程序的基本需要
-
在Java语言中,提供了基础的基于Timer和ScheduledExecutorService线程池的定时任务处理
-
在Spring Boot中,支持注解式、编程式、平台式种方式实现定时任务
-
注解式
-
简单、易用,但不够灵活
-
与项目集成一体,通用性不强,项目停止,定时功能也终止
-
主要注解有
-
@EnableScheduling:启用定时任务注解,标识启动类
-
@Scheduled:定时任务逻辑方法注解,配合Cron表达式,可在程序启动后,按要求执行定时任务
-
-
-
编程式
-
一般使用Quartz等框架实现
-
灵活,需要编写一些代码
-
-
平台式
-
独立于单个业务项目,让业务项目专注于业务,只要提供回调接口
-
一般会提供所有定时任务查看,并能对所有任务进行管理,更符合企业需要
-
常用的任务调用平台有SchedulerX、XXL-JOB等
-
-
Cron表达式
-
针对定时的规则,有很多种表达方式,比如5分钟后执行、明天5点执行、每周二早上10点执行等
-
为了表达这些灵活且多样化的时间规则,通常会使用Cron表达式进行
-
Cron表达式规则:通过类似时间倒置形式,以5或6个空格隔开,分为6或7个段,每一个段代表一个时间部分,常见以下两种格式
-
秒 分 小时 每月第几天 月份 每周第几天 年
-
秒 分 小时 每月第几天 月份 每周第几天
其中蓝色和红色互斥,但配置其中一个,另一个为配置为?
-
-
Cron主要规则如下图
Cron表达式图 -
Cron表达式中的符号意义
-
*:表示所有可能的值
-
/:表示数值的增量,简单来说,比如分写上0/5表示从0分开始,每隔5分钟
-
?:仅用在天(月)和天(周),表示不指定值,当其中一个有值时,另外一个需要设为?
-
L:last,表示一月的最后一天或一周的最后一天
-
W:work,表示有效工作日(周一到周五)
-
-
Cron表达式实例
-
0 0 12 * * ? 每天中午12点触发1次
-
0 0/30 * * * ? 每30分钟触发1次
-
0 0 12 ? * 2-6 周一至周五的12点触发1次
-
3 25 19 26 8 ? 2029 指定时间点执行1次
-
注解式
概述
-
直接在项目中使用,简单、易用
-
使用@Schedule注解
-
@Schedule中可配置几种方式
-
cron,定时
-
fixRate,固定频率
-
fixDelay,固定延迟
-
使用步骤
-
添加启动注解:在启动类上添加@EnableScheduling注解
-
添加定时任务方法:按照业务需要添加定时任务方法,并在方法上加上@Scheduled注解;见附件项目中的job.ScheduledJob类
-
自动生效:程序启动后,自动生效
【演示】
-
Spring Boot中使用声明式定时任务,见附件项目springboot-schedule-annotation
【练习】
-
练习实例内容,完成代码编写
Quartz【了解】
概述
-
OpenSymphony开源组织在任务调度领域的一个开源项目,完全由Java开发,可以用来执行定时任务,其特点有:
-
作业持久性:就是保持调度定时的状态,并落地到数据库
-
作业管理:对调度作业进行有效的管理,比如手动启动、停止等操作
-
-
常见的应用场景:购票/购物付款的到期订单作废;自定义的消息提醒;job作业平台等
-
特点:灵活,易用;与项目强耦合,不能面向多个项目;项目停止定时也终止;可开发定时任务平台
使用步骤
-
添加依赖:在pom.xml中添加依赖
<!--【Quartz】1、添加依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
-
添加启动注解:在启动类上添加@ EnableScheduling注解
-
添加定时任务:定义Job,继承QuartzJobBean,并覆写其executeInternal方法
-
注入任务详情与触发器:将自定义JobDetail和Trigger注入Spring容器,里面包含cron表达式
【演示】
-
Spring Boot中使用quartz定时任务,见附件项目springboot-schedule-quartz
XXL-JOB
概述
-
一个高效、易用、灵活的分布式调度平台,开箱即用,且开源、易扩展
-
分任务调度中心和执行器,能做到完全与业务分离,适合企业众多业务系统对任务调度都有需要的场景
-
数据落地到数据库,还提供重试等机制
-
完全基于Spring Boot技术开源项目,GitHub的Star超过25k
-
特点:独立、易用、中立、平台化;与实际项目解耦,不受单个项目终止影响,满足企业实际需要
-
业务示意图如下
使用步骤
准备.下载官方源代码及文档,地址为https://www.xuxueli.com/xxl-job/
-
部署XXL-JOB数据库,创建一个xxl_job的数据库,并使用官方提供的脚本doc\db\tables_xxl_job.sql初始数据库结构
-
部署XXL-JOB调度中心
-
使用开源代码xxl-job-admin项目
-
将application.properties中数据库连接改成第1步部署的数据库,并可配置访问端口
-
启动项目,然后通过http://ip:端口/xxl-job-admin/访问,初始用户名和密码为admin和123456
-
-
部署XXL-JOB执行器
-
使用开源代码xxl-job-executor-samples/xxl-job-executor-sample-springboot
-
将application.properties中xxl.job.admin.addresses指向调度中心地址,并可配置访问端口
-
启动项目,执行器自身会开启一个9999的端口给调度中心调用
-
-
业务服务中使用XXL-JOB,多个业务服务就能直接使用第2步调度中心的API新建定时任务、停止定时任务;使用大概过程如下
-
添加XXL-JOB任务调度中心地址配置,在application.properties中添加配置
#【使用XXL-JOB】1、添加XXL-JOB任务调度中心地址配置 #调度中心地址 xxl.job.admin.address=http://localhost:8080/xxl-job-admin #用户名 xxl.job.admin.user_name=admin #密码 xxl.job.admin.password=123456 #接入系统名称 xxl.job.system.name=order-system
-
封装XXL-JOB调用工具类,通过使用RestTemplate对XXL-JOB任务调度中心API的调用,往XXL-JOB任务调度中心添加定时任务、删除定时任务;具体见附件项目中的util.XxlJobUtil类
-
添加定时任务方法addJob,主要传入参数为cron、定时执行的回调URL,返回参数中包含定时任务id,一般要与业务数据关联
-
停止定时任务方法stopJob,主要传入参数为定时任务id,停止指定业务数据关联的定时任务
-
获取登录票据方法getLoginInfo,使用XXL-JOB任务调度中心的登录功能获取登录票据
-
-
使用XXL-JOB调用工具类,在业务中,就可以使用封装的XXL-JOB工具类创建定时任务、停止定时任务;具体见附件代码中的controller.OrderController类、controller.OrderCallbackController类
-
【演示】
-
Spring Boot中使用XXL-JOB,模拟一个订单下单等待支付、主动支付关闭订单、支付超时关闭订单业务场景,见附件项目xxl-job-2.4.0、springboot-schedule-xxl-job
代码
网盘地址:链接:https://pan.baidu.com/s/1Jkzxt1-GGZ-GNp_VQ2C9SA?pwd=8888