1. 定时任务
为什么需要定时任务?
时间驱动处理场景: 整点发送优惠券,每天更新收益,每天刷新标签数据和人群数据。
批量处理数据: 按月批量统计报表数据,批量更新短信状态,实时性要求不高。
异步执行解耦: 活动状态刷新,数据同步,异步执行离线查询,与内部逻辑解耦。
实现方式:
- jdk方式:死循环、Timer定时器、JUC定时任务等
- springScheduling声明式定时任务:@EnableScheduling、@Scheduled
- 永远的经典:定时任务框架quartz
- 分布式定时任务:xxl-job(基于quartz)、elastic-Job(基于quartz)、Saturn(elastic-job的fork版本)
- MQ延时队列
等等。。。。。。。。。
各个解决方案的优缺点:
- jdk方式及springScheduling不支持高可用,不支持动态配置
- quartz支持高可用(非常麻烦,需要10几张表),不支持动态配置
- xxl-job支持高可用,动态配置以及任务的同一管理
2. 分布式定时任务xxl-Job
xxl(作者:许雪里)官方网站:https://www.xuxueli.com/xxl-job
分布式任务调度框架几乎是每个大型应用必备的工具。XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。
目前已有多家公司接入xxl-job,包括比较知名的大众点评,京东,优信二手车,北京尚德,360金融 (360),联想集团 (联想),易信 (网易)等等…
2.1. 项目结构
XXL-JOB支持通过 Web 页面对任务进行 CRUD 操作,支持动态修改任务状态、暂停/恢复任务,以及终止运行中任务,支持在线配置调度任务入参和在线查看调度结果。
源码参照github:https://github.com/xuxueli/xxl-job
码云:http://gitee.com/xuxueli0323/xxl-job
xxl-job-admin:调度中心
xxl-job-core:公共依赖
xxl-job-executor-samples:执行器Sample示例(选择合适的版本执行器,可直接使用,也可以参考其并将现有项目改造成执行器)
:xxl-job-executor-sample-springboot:Springboot版本管理执行器,推荐这种方式
:xxl-job-executor-sample-spring:Spring版本,通过Spring容器管理执行器,比较通用
:xxl-job-executor-sample-frameless:无框架版本
:xxl-job-executor-sample-jfinal:JFinal版本,通过JFinal管理执行器
:xxl-job-executor-sample-nutz:Nutz版本,通过Nutz管理执行器
:xxl-job-executor-sample-jboot:jboot版本,通过jboot管理执行器
调度中心:统一管理任务调度平台上的调度任务,负责触发调度执行,并且提供任务管理平台。
执行器:负责接收“调度中心”的调度并执行;可直接部署执行器,也可以将执行器集成到现有业务项目中。
设计思想:
将调度行为抽象形成“调度中心”公共平台,而平台自身并不承担业务逻辑,“调度中心”负责发起调度请求。
将任务抽象成分散的JobHandler,交由“执行器”统一管理,“执行器”负责接收调度请求并执行对应的JobHandler中业务逻辑。
因此,“调度”和“任务”两部分可以相互解耦,提高系统整体稳定性和扩展性;
2.2. 部署调度中心
2.2.1. 初始化“调度数据库”
请下载项目源码并解压,获取 “调度数据库初始化SQL脚本” 并执行即可。
“调度数据库初始化SQL脚本” 位置为:/xxl-job/doc/db/tables_xxl_job.sql
调度中心支持集群部署,集群情况下各节点务必连接同一个mysql实例;如果mysql做主从,调度中心集群节点务必强制走主库。
导入mysql数据库,效果如下:
表说明(了解):
- xxl_job_lock:任务调度锁表。
- xxl_job_group:执行器信息表,维护任务执行器信息。
- xxl_job_info:调度扩展信息表: 用于保存XXL-JOB调度任务的扩展信息,如任务分组、任务名、机器地址、执行器、执行入参和报警邮件等等。
- xxl_job_log:调度日志表: 用于保存XXL-JOB任务调度的历史信息,如调度结果、执行结果、调度入参、调度机器和执行器等等。
- xxl_job_log_report:调度日志报表:用户存储XXL-JOB任务调度日志的报表,调度中心报表功能页面会用到。
- xxl_job_logglue:任务GLUE日志:用于保存GLUE更新历史,用于支持GLUE的版本回溯功能。
- xxl_job_registry:执行器注册表,维护在线的执行器和调度中心机器地址信息。
- xxl_job_user:系统用户表。
2.2.2. 修改“调度中心”配置
调度中心配置文件:/xxl-job/xxl-job-admin/src/main/resources/application.properties
主要关注以下3部分配置:端口号、jdbc数据源、报警邮箱、xxl调度中心配置
### 端口号
server.port=8080
### 调度中心JDBC链接:链接地址请保持和 调度数据库的地址一致
spring.datasource.url=jdbc:mysql://172.16.116.100:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
### 报警邮箱
spring.mail.host=smtp.qq.com
spring.mail.port=25
[email protected]
spring.mail.password=xxx
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
### 调度中心通讯TOKEN [选填]:非空时启用;
xxl.job.accessToken=
### 调度中心国际化配置 [必填]: 默认为 "zh_CN"/中文简体, 可选范围为 "zh_CN"/中文简体, "zh_TC"/中文繁体 and "en"/英文
xxl.job.i18n=zh_CN
## 调度线程池最大线程配置【必填】
xxl.job.triggerpool.fast.max=200
xxl.job.triggerpool.slow.max=100
### 调度中心日志表数据保存天数 [必填]:过期日志自动清理;限制大于等于7时生效,否则, 如-1,关闭自动清理功能;
xxl.job.logretentiondays=30
2.2.3. 打包运行”调度中心“
切换到xxl-job\xxl-job-admin项目目录下。
将项目编译打包:mvn clean package -Dmaven.skip.test=true
打包成功后,切换到target目录:cd target
启动调度中心:java -jar xxl-job-admin-2.2.0.jar 或者 java -jar -Dserver.port=8088 xxl-job-admin-2.2.0.jar
在浏览器访问:http://localhost:8080/xxl-job-admin/
默认登录账号 “admin/123456”, 登录后运行界面如下图所示。
至此“调度中心”项目已经部署成功。
2.2.4. ”调度中心“集群(可选)
调度中心支持集群部署,提升调度系统容灾和可用性。
调度中心集群部署时,几点要求和建议:
- DB配置保持一致;
- 集群机器时钟保持一致(单机集群忽视);
- 建议:推荐通过nginx为调度中心集群做负载均衡,分配域名。调度中心访问、执行器回调配置、调用API服务等操作均通过该域名进行。
2.2.5. Docker镜像搭建调度中心
- 下载镜像
// Docker地址:https://hub.docker.com/r/xuxueli/xxl-job-admin/ (建议指定版本号)docker pull xuxueli/xxl-job-admin
- 创建容器并运行
docker run -p 8080:8080 -v /tmp:/data/applogs --name xxl-job-admin -d xuxueli/xxl-job-admin:{
指定版本}
/**
* 如需自定义 mysql 等配置,可通过 "-e PARAMS" 指定
* 参数格式 PARAMS="--key=value --key2=value2" ;
* 配置项参考文件:/xxl-job/xxl-job-admin/src/main/resources/application.properties
* 如需自定义 JVM内存参数 等配置,可通过 "-e JAVA_OPTS" 指定,参数格式 JAVA_OPTS="-Xmx512m" ;
*/
docker run -e PARAMS="--spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai" -p 8080:8080 -v /tmp:/data/applogs --name xxl-job-admin -d xuxueli/xxl-job-admin:{
指定版本}
2.3. 搭建执行器项目
执行器负责接收“调度中心”的调度并执行;在源码中作者已经贴心的给出了多种执行器项目示例(官方推荐的xxl-job-executor-sample-springboot项目为例部署),可根据你的喜好直接将其部署作为你自己的执行器,当然你也可以将执行器集成到现有业务项目中去
这里以集成到现有项目为例,将执行器集成到现有的项目中去。(参照xxl-job-executor-sample-springboot)
2.3.1. 添加xxl-job-core依赖
pom.xml中需要有这两个基本依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.2.0</version>
</dependency