XXL-JOB任务调度

简介:
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、内存、磁盘、带宽等的影响。所以集群是有必要的。
XXL-JOB任务调度_第1张图片

快速开始

XXL-JOB任务调度_第2张图片

任务调度中心

1、下载项目
通过git拉去项目(https://gitee.com/xuxueli0323/xxl-job)
2、初始化数据库
执行 doc\db 下的sql文件。
XXL-JOB任务调度_第3张图片
3、修改调度中心配置文件
打开下载的项目文件,修改properties文件(项目端口、数据库信息)。
XXL-JOB任务调度_第4张图片
4、启动调度中心
首次访问(http://localhost:8080/xxl-job-admin/)需要输入账号密码admin 123456

XXL-JOB任务调度_第5张图片

执行器

1、 新建springboot项目,jdk11,勾选 spring web 依赖。
2、添加xxl-job依赖

<dependency>
            <groupId>com.xuxueligroupId>
            <artifactId>xxl-job-coreartifactId>
            <version>2.3.1version>
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、启动执行,在调度中心中可查看执行器信息
XXL-JOB任务调度_第6张图片

7、编写cron表达式,然后在操作中点击执行则可以启动任务。通过JobHandler中的名称找到一致名称@XxlJob注解多代表的方法
XXL-JOB任务调度_第7张图片
XXL-JOB任务调度_第8张图片

GLUE模式

不需要指定Handler,原理就是在任务调度中心中编写代码,然后将代码发送至执行器,执行器执行。这里使用了@Autowired、@Resource等注解。

1、点击新增,在运营模式中选择GLUE(java)。
2、在编写GLUE代码(注意引用相关包)
XXL-JOB任务调度_第9张图片

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}
             */
        }
    }

你可能感兴趣的:(工具,java,spring,后端)