文章目录
- 1 xxl-job 快速入门
- 1.1 xxl-job是什么
- 1.2 为什么需要xxl-job
- 1.2.1 定时任务
- 1.2.2 分布式任务调度
- 1.2.3 分布式任务调度特点
- 1.3 xxl-job简介
- 1.4 部署安装——基于docker
- 1.5 xxl-job表介绍
- 1.5 编写任务代码
- 1.5.1 xxl-job配置
- 1.5.2 任务代码
- 1.5.3 分布式任务测试
- 1.5.3.1 先把本地服务器跑起来
- 1.5.3.2 新增执行器管理
- 1.5.3.3 新增任务管理
- 1.5.3.4 启动任务
- 1.5.3.5 执行任务
- 1.6 调度流程
- 1.6.1 任务调度时序图
- 1.6.2 任务调度原理
1 xxl-job 快速入门
1.1 xxl-job是什么
xxl-job的功能可以联系
Spring Task定时任务处理
,其不同点在Spring Task不适于分布式中,而xxl-job适用于分布式系统中。
1.2 为什么需要xxl-job
一般在项目中实现
定时任务
主要有两种技术方案,分别是Spring Task和xxl-job
,其中Spring Task
适合单体项目
,而xxl-job
适合与分布式任务
调度框架,更适合于在分布式项目中使用。
1.2.1 定时任务
在某一时间段,或者某一时间点定时处理某一任务。
1.2.2 分布式任务调度
分布式任务调度介绍:在微服务架构体系中,服务间通过网络交互来完成业务,在分布式框架下,一个服务需要部署多个实例来确保业务的可靠运行,在这种分布式环境下运行任务调度,称之为分布式任务调度。
1.2.3 分布式任务调度特点
特点 | 说明 |
---|---|
并行任务调度 | 集群部署单个服务, 这样就可以使多台计算机共同去完成任务调度,将任务(方法)分割成若干分片,交由不同实例并行执行,以提高任务调度的处理效率 |
高可用 | 若某一个实例宕机,不影响其他实例来执行任务。 |
弹性扩容 | 当集群中增加实例就可以提高执行任务效率。 |
任务管理与监测 | ① 对系统中存在的所有定时任务进行统一管理与监测。②让开发人员能时刻了解任务执行情况,从而做出快速处理响应。 |
1.3 xxl-job简介
XXL-JOB:其是一个分布式调度平台,设计目的:开发迅速、学习简单、开箱即用。
官方网址:https://www.xuxueli.com/xxl-job/
官方架构图:
1.4 部署安装——基于docker
docker run \
-e PARAMS="--spring.datasource.url=jdbc:mysql://192.168.150.101:3306/xxl_job?Unicode=true&characterEncoding=UTF-8 \
--spring.datasource.username=root \
--spring.datasource.password=123" \
--restart=always \
-p 28080:8080 \
-v xxl-job-admin-applogs:/data/applogs \
--name xxl-job-admin \
-d \
xuxueli/xxl-job-admin:2.3.0
- 默认端口映射到28080
- 日志挂载到/var/lib/docker/volumes/xxl-job-admin-applogs
- 数据库脚本:https://gitee.com/xuxueli0323/xxl-job/blob/2.3.0/doc/db/tables_xxl_job.sql
1.5 xxl-job表介绍
表 | 说明 |
---|---|
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 | 系统用户表。 |
1.5 编写任务代码
1.5.1 xxl-job配置
package com.sl.xxljob.config;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* xxl-job config
*/
@Configuration
public class XxlJobConfig {
private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
@Value("${xxl.job.accessToken:}")
private String accessToken;
@Value("${xxl.job.executor.appname}")
private String appname;
@Value("${xxl.job.executor.address:}")
private String address;
@Value("${xxl.job.executor.ip:}")
private String ip;
@Value("${xxl.job.executor.port:0}")
private int port;
@Value("${xxl.job.executor.logpath:}")
private String logPath;
@Value("${xxl.job.executor.logretentiondays:}")
private int logRetentionDays;
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
logger.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appname);
xxlJobSpringExecutor.setAddress(address);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
}
1.5.2 任务代码
package com.sl.xxljob.job;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
/**
* 任务处理器
*/
@Component
public class JobHandler {
private List<Integer> dataList = Arrays.asList(1, 2, 3, 4, 5);
/**
* 普通任务
*/
@XxlJob("firstJob")
public void firstJob() throws Exception {
System.out.println("firstJob执行了.... " + LocalDateTime.now());
for (Integer data : dataList) {
XxlJobHelper.log("data= {}", data);
Thread.sleep(RandomUtil.randomInt(100, 500));
}
System.out.println("firstJob执行结束了.... " + LocalDateTime.now());
}
/**
* 分片式任务
*/
@XxlJob("shardingJob")
public void shardingJob() throws Exception {
// 分片参数
// 分片节点总数
int shardTotal = XxlJobHelper.getShardTotal();
// 当前节点下标,从0开始
int shardIndex = XxlJobHelper.getShardIndex();
System.out.println("shardingJob执行了.... " + LocalDateTime.now());
for (Integer data : dataList) {
if (data % shardTotal == shardIndex) {
XxlJobHelper.log("data= {}", data);
Thread.sleep(RandomUtil.randomInt(100, 500));
}
}
System.out.println("shardingJob执行结束了.... " + LocalDateTime.now());
}
}
1.5.3 分布式任务测试
1.5.3.1 先把本地服务器跑起来
1.5.3.2 新增执行器管理
1.5.3.3 新增任务管理
1.5.3.4 启动任务
1.5.3.5 执行任务
1.6 调度流程
1.6.1 任务调度时序图
1.6.2 任务调度原理
原理:
- ① 首先,用户在开发者服务器想要执行的方法上使用
@XxlJob()
,标识此是一个调度任务及其任务名,随后启动服务器,服务器就会把自己注册到xxl-job调度中心。- ② 随后,用户在调度中心上创建定时任务及其任务启动规则,并启动此调度任务后,调度中心就会向开发者服务器,发送
http请求
。- ③ 其次,开发者服务器在接受到调度中心发送的http请求后,便会根据调度中心中用户设置的服务器名称(开发者服务器配置文件中已经配置)和JobHandle(被开发者服务器上用
@XxlJob("shardingJob")声明的方法
),执行响应任务。- ④然后,开发者服务器便会通过http请求向调度中心反馈任务执行结果,调度中心再接收到反馈后,便会记录日志,以便与用户查看日志。