简介:
XXL-JOB 是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。
官网:https://www.xuxueli.com/xxl-job/
以下业务场景可用任务解决
- 某电商平台需要每天上午10点,下午3点,晚上8点发放批优惠券
- 某银行系统需要在信用卡到期还款日的前三天进行短信提醒
- 某财务系统需要在每天凌晨0:10分结算前一天的财务数据,统计汇总
为什么要使用任务调用
使用spring的 @Schedule 也能完成调度的功能(在启动类上贴上@EnableSchedule注解)
@Scheduled(cron = "0/3 * * * * ?")
public void work(){
//dosomething
}
1、单点故障:单机版的定时任务调度只能在一台机器上运行,如果程序出现异常导致功能不能用。
2、防止重复执行:多台服务器任务时间统一控制,防止出现重复执行和混乱。
3、提高效率:单机即使使用多线程、多进程,其吞吐量也会受到cpu、内存、磁盘、带宽等的影响。所以集群是有必要的。
快速开始
任务调度中心
1、下载项目
通过git拉去项目(https://gitee.com/xuxueli0323/xxl-job)
2、初始化数据库
执行 doc\db 下的sql文件。
3、修改调度中心配置文件
打开下载的项目文件,修改properties文件(项目端口、数据库信息)。
4、启动调度中心
首次访问(http://localhost:8080/xxl-job-admin/)需要输入账号密码admin 123456
执行器
1、 新建springboot项目,jdk11,勾选 spring web 依赖。
2、添加xxl-job依赖
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.3.1</version>
</dependency>
3、编写properties文件
server.port=8888
# 调度中心部署根地址[选填](集群则用逗号隔开)。执行器会使用该地址进行“执行器心跳注册”和“任务结果回调”
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
# 执行器通讯token[选填]非空时使用
xxl.job.accessToken=default_token
# 执行器AppName[选填]:执行器心跳注册分组依据,为空时关闭自动注册
xxl.job.executor.appname=xxl-job-executor-sample
# 执行器注册地址[选填]:优先使用,为空时使用内嵌服务“ip:port”作为注册地址
xll.job.executor.address=
# 执行器ip[选填]:默认为空则表示自动获取ip,多网卡时可以手动设置指定ip
xll.job.executor.ip=127.0.0.1
# 执行器端口[选填]:默认为9999
xxl.kob.executor.port=9999
# 执行器日志文件保存路径[选填],为空默认路径
xxl.job.executor.logpath=
# 日志保存天数
xxl.job.executor.logretentiondays=30
4、在配置类中创建 XxlJobSpringExecutor 对象,引入配置文件中的属性。
@Configuration
public class XxlJobConfig {
@Value("${xxl.job.admin.addresses}")
private String adminAddress;
@Value("${xxl.job.accessToken}")
private String accessToken;
@Value("${xxl.job.executor.appname}")
private String appname;
@Value("${xll.job.executor.address}")
private String address;
@Value("${xll.job.executor.ip}")
private String ip;
@Value("${xxl.kob.executor.port}")
private int port;
@Value("${xxl.job.executor.logpath}")
private String logPath;
@Value("${xxl.job.executor.logretentiondays}")
private int logRetentionDays;
@Bean
public XxlJobSpringExecutor xxlJobSpringExecutor(){
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddress);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setAppname(appname);
xxlJobSpringExecutor.setAddress(address);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
}
5、书写业务类,实现具体的任务方法(使用@XxlJob注解声明处理器)。
@XxlJob("demoJobHandler")
public void demoJobHandler()throws Exception{
System.out.println("执行定时任务:执行时间:"+ new Date());
}
6、启动执行,在调度中心中可查看执行器信息
7、编写cron表达式,然后在操作中点击执行则可以启动任务。通过JobHandler中的名称找到一致名称@XxlJob注解多代表的方法
GLUE模式
不需要指定Handler,原理就是在任务调度中心中编写代码,然后将代码发送至执行器,执行器执行。这里使用了@Autowired、@Resource等注解。
1、点击新增,在运营模式中选择GLUE(java)。
2、在编写GLUE代码(注意引用相关包)
package com.xxl.job.service.handler;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.IJobHandler;
import org.springframework.beans.factory.annotation.Autowired;
import com.linxi.xxljob_demo.service.HelloService;
public class DemoGlueJobHandler extends IJobHandler {
@Autowired
private HelloService helloService;
@Override
public void execute() throws Exception {
helloService.methedA();
}
}
分片广播
将任务下发给所有执行器,执行器条件过滤选择自己的任务进行执行。并行 => 提高吞吐量。
分片任务场景:10个执行器的集群来处理10w条数据,每台机器只需要处理1w条数据,耗时降低10倍;
int shardIndex = XxlJobHelper.getShardIndex();
int shardTotal = XxlJobHelper.getShardTotal();
index:当前分片序号(从0开始),执行器集群列表中当前执行器的序号;
total:总分片数,执行器集群的总机器数量;
@XxlJob("sendMsg")
public void sendMsg() throws Exception {
int shardIndex = XxlJobHelper.getShardIndex();//获取当前分片的序号
int shardTotal = XxlJobHelper.getShardTotal();//分片总数
if (shardTotal == 1) {
//TODO 只有一个执行器
} else {
//TODO 多个执行器并行分发任务并行开始
/*
select * from table m
where m.id % #{shareTotal} = #{shareIndex}
limit #{count}
*/
}
}