11. 集成 xxl-job
11. 集成 xxl-job
1.简介
xxl-job: 是一个分布式任务调度平台。平台架构分为 “调度中心” 和 “执行器”。调度中心类似定时任务的注册中心,用于统一管理定时任务;执行器用于执行定时任务。
注意: xxl-job 集成不同于其他项目,xxl-job 本身有非常完整的文档和代码示例,本文只是精简记录集成步骤。
环境: Maven3+、Jdk1.8+、Mysql5.7+
官网地址: https://www.xuxueli.com/index.html
官方文档: https://www.xuxueli.com/xxl-job/
官方代码示例-GitHub: https://github.com/xuxueli/xxl-job
官方代码示例-Gitee: https://gitee.com/xuxueli0323/xxl-job
2.Maven 依赖
<!-- http://repo1.maven.org/maven2/com/xuxueli/xxl-job-core/ -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>${最新稳定版本}</version>
</dependency>
3.初始化数据库
- xxl_job_lock:任务调度锁表;
- xxl_job_info:调度扩展信息表;
- xxl_job_group:执行器信息表;
- xxl_job_log:调度日志表;
- xxl_job_log_report:调度日志报表;
- xxl_job_logglue:任务 GLUE 日志;
- xxl_job_registry:执行器注册表,维护在线的执行器和调度中心机器地址信息;
- xxl_job_user:系统用户表。
#
# XXL-JOB v2.4.0-SNAPSHOT
# Copyright (c) 2015-present, xuxueli.
CREATE database if NOT EXISTS xxl_job default character set utf8mb4 collate utf8mb4_unicode_ci;
use xxl_job;
SET NAMES utf8mb4;
CREATE TABLE xxl_job_info (
id int(11) NOT NULL AUTO_INCREMENT,
job_group int(11) NOT NULL COMMENT '执行器主键ID',
job_desc varchar(255) NOT NULL,
add_time datetime DEFAULT NULL,
update_time datetime DEFAULT NULL,
author varchar(64) DEFAULT NULL COMMENT '作者',
alarm_email varchar(255) DEFAULT NULL COMMENT '报警邮件',
schedule_type varchar(50) NOT NULL DEFAULT 'NONE' COMMENT '调度类型',
schedule_conf varchar(128) DEFAULT NULL COMMENT '调度配置,值含义取决于调度类型',
misfire_strategy varchar(50) NOT NULL DEFAULT 'DO_NOTHING' COMMENT '调度过期策略',
executor_route_strategy varchar(50) DEFAULT NULL COMMENT '执行器路由策略',
executor_handler varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
executor_param varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
executor_block_strategy varchar(50) DEFAULT NULL COMMENT '阻塞处理策略',
executor_timeout int(11) NOT NULL DEFAULT '0' COMMENT '任务执行超时时间,单位秒',
executor_fail_retry_count int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数',
glue_type varchar(50) NOT NULL COMMENT 'GLUE类型',
glue_source mediumtext COMMENT 'GLUE源代码',
glue_remark varchar(128) DEFAULT NULL COMMENT 'GLUE备注',
glue_updatetime datetime DEFAULT NULL COMMENT 'GLUE更新时间',
child_jobid varchar(255) DEFAULT NULL COMMENT '子任务ID,多个逗号分隔',
trigger_status tinyint(4) NOT NULL DEFAULT '0' COMMENT '调度状态:0-停止,1-运行',
trigger_last_time bigint(13) NOT NULL DEFAULT '0' COMMENT '上次调度时间',
trigger_next_time bigint(13) NOT NULL DEFAULT '0' COMMENT '下次调度时间',
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE xxl_job_log (
id bigint(20) NOT NULL AUTO_INCREMENT,
job_group int(11) NOT NULL COMMENT '执行器主键ID',
job_id int(11) NOT NULL COMMENT '任务,主键ID',
executor_address varchar(255) DEFAULT NULL COMMENT '执行器地址,本次执行的地址',
executor_handler varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
executor_param varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
executor_sharding_param varchar(20) DEFAULT NULL COMMENT '执行器任务分片参数,格式如 1/2',
executor_fail_retry_count int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数',
trigger_time datetime DEFAULT NULL COMMENT '调度-时间',
trigger_code int(11) NOT NULL COMMENT '调度-结果',
trigger_msg text COMMENT '调度-日志',
handle_time datetime DEFAULT NULL COMMENT '执行-时间',
handle_code int(11) NOT NULL COMMENT '执行-状态',
handle_msg text COMMENT '执行-日志',
alarm_status tinyint(4) NOT NULL DEFAULT '0' COMMENT '告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败',
PRIMARY KEY (id),
KEY I_trigger_time (trigger_time),
KEY I_handle_code (handle_code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE xxl_job_log_report (
id int(11) NOT NULL AUTO_INCREMENT,
trigger_day datetime DEFAULT NULL COMMENT '调度-时间',
running_count int(11) NOT NULL DEFAULT '0' COMMENT '运行中-日志数量',
suc_count int(11) NOT NULL DEFAULT '0' COMMENT '执行成功-日志数量',
fail_count int(11) NOT NULL DEFAULT '0' COMMENT '执行失败-日志数量',
update_time datetime DEFAULT NULL,
PRIMARY KEY (id),
UNIQUE KEY i_trigger_day (trigger_day) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE xxl_job_logglue (
id int(11) NOT NULL AUTO_INCREMENT,
job_id int(11) NOT NULL COMMENT '任务,主键ID',
glue_type varchar(50) DEFAULT NULL COMMENT 'GLUE类型',
glue_source mediumtext COMMENT 'GLUE源代码',
glue_remark varchar(128) NOT NULL COMMENT 'GLUE备注',
add_time datetime DEFAULT NULL,
update_time datetime DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE xxl_job_registry (
id int(11) NOT NULL AUTO_INCREMENT,
registry_group varchar(50) NOT NULL,
registry_key varchar(255) NOT NULL,
registry_value varchar(255) NOT NULL,
update_time datetime DEFAULT NULL,
PRIMARY KEY (id),
KEY i_g_k_v (registry_group,registry_key,registry_value)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE xxl_job_group (
id int(11) NOT NULL AUTO_INCREMENT,
app_name varchar(64) NOT NULL COMMENT '执行器AppName',
title varchar(12) NOT NULL COMMENT '执行器名称',
address_type tinyint(4) NOT NULL DEFAULT '0' COMMENT '执行器地址类型:0=自动注册、1=手动录入',
address_list text COMMENT '执行器地址列表,多地址逗号分隔',
update_time datetime DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE xxl_job_user (
id int(11) NOT NULL AUTO_INCREMENT,
username varchar(50) NOT NULL COMMENT '账号',
password varchar(50) NOT NULL COMMENT '密码',
role tinyint(4) NOT NULL COMMENT '角色:0-普通用户、1-管理员',
permission varchar(255) DEFAULT NULL COMMENT '权限:执行器ID列表,多个逗号分割',
PRIMARY KEY (id),
UNIQUE KEY i_username (username) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE xxl_job_lock (
lock_name varchar(50) NOT NULL COMMENT '锁名称',
PRIMARY KEY (lock_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO xxl_job_group(id, app_name, title, address_type, address_list, update_time) VALUES (1, 'xxl-job-executor-sample', '示例执行器', 0, NULL, '2018-11-03 22:21:31' );
INSERT INTO xxl_job_info(id, job_group, job_desc, add_time, update_time, author, alarm_email, schedule_type, schedule_conf, misfire_strategy, executor_route_strategy, executor_handler, executor_param, executor_block_strategy, executor_timeout, executor_fail_retry_count, glue_type, glue_source, glue_remark, glue_updatetime, child_jobid) VALUES (1, 1, '测试任务1', '2018-11-03 22:21:31', '2018-11-03 22:21:31', 'XXL', '', 'CRON', '0 0 0 * * ? *', 'DO_NOTHING', 'FIRST', 'demoJobHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2018-11-03 22:21:31', '');
INSERT INTO xxl_job_user(id, username, password, role, permission) VALUES (1, 'admin', 'e10adc3949ba59abbe56e057f20f883e', 1, NULL);
INSERT INTO xxl_job_lock ( lock_name) VALUES ( 'schedule_lock');
commit;
4.调度中心配置
xxl-job-admin/src/main/resources/application.properties
### 调度中心JDBC链接:链接地址请保持和 2.1章节 所创建的调度数据库的地址一致
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root_pwd
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
### 报警邮箱
spring.mail.host=smtp.qq.com
spring.mail.port=25
spring.mail.username=xxx@qq.com
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
5.执行器配置
xxl-job-executor-sample-springboot/src/main/resources/application.properties
### 调度中心部署根地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
### 执行器通讯TOKEN [选填]:非空时启用;
xxl.job.accessToken=
### 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
xxl.job.executor.appname=xxl-job-executor-sample
### 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。
xxl.job.executor.address=
### 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务";
xxl.job.executor.ip=
### 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
xxl.job.executor.port=9999
### 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
### 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
xxl.job.executor.logretentiondays=30
6.项目结构
启动顺序:
1、 xxl-job-admin,调度中心;
2、 xxl-job-executor-sample-springboot,执行器;
7.访问页面
访问地址: http://localhost:8080/xxl-job-admin
登录账号: admin/123456
8.新建定时任务
1)在任务管理点击“新建”。
2)输入相应的信息。
其中运行模式有 7 种,这里介绍其中 Java 相关的两种:BEAN、GLUE(Java)
9.BEAN 运行模式
BEAN 运行模式有两种实现方式:
- 方法形式: 通过 @XxlJob 注解修饰方法;
/**
* 1、简单任务示例(Bean模式)
*/
@XxlJob("demoJobHandler")
public void demoJobHandler() throws Exception {
XxlJobHelper.log("XXL-JOB, Hello World.");
for (int i = 0; i < 5; i++) {
XxlJobHelper.log("beat at:" + i);
TimeUnit.SECONDS.sleep(2);
}
// default success
}
- 类形式: 非 springboot 项目,在启动 main 方法中配置注册类,并使用 @XxlJob 注解修饰方法。
// registry job bean
xxlJobExecutor.setXxlJobBeanList(Arrays.asList(new SampleXxlJob()));
10.GLUE(Java)运行模式
1)新建任务之后,可以点击“操作”按钮右边的下拉框,选择“GLUE IDE”。
2)定制想要实现的 Java 代码,例如增加一行输出到控制台。
3)执行定时任务。
4)调度日志菜单中有了任务的执行记录。
5)执行器的控制台打印了 test。
11.补充说明
1)任务执行器报错:java.lang.RuntimeException: xxl-job method-jobhandler param-classtype invalid
具体报错如下:
java.lang.RuntimeException: xxl-job method-jobhandler param-classtype invalid, for[class com.demo.schedual.MySchedule#checkAndUpdateStatus] , The correct method format like " public ReturnT<String> execute(String param) " .
at com.xxl.job.core.executor.impl.XxlJobSpringExecutor.initJobHandlerMethodRepository(XxlJobSpringExecutor.java:127)
at com.xxl.job.core.executor.impl.XxlJobSpringExecutor.afterSingletonsInstantiated(XxlJobSpringExecutor.java:41)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:864)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204)
at com.demo.DemoApplication.main(MobileCenterApplication.java:35)
报错原因:
定时任务的方法必须是这种形式:public ReturnT<String> execute(String param)
需要注意两点:
1、 入参必须是 Stringparam<String>;
2、 返回值必须是 ReturnT<String>;
2)cron 中 0/5 和 */5 有什么区别?
在 cron 中,“0/5” 和 “*/5” 都表示以步长为 5 的间隔执行任务,但它们在具体使用时稍有不同:
- 0/5:表示从 0 开始,每隔 5 个单位执行一次。
- */5:表示从最小允许值开始,每个 5 个单位执行一次。
整理完毕,完结撒花~