XXL-JOB定时任务(可以直接上手简单使用)

借鉴大佬的,写这个博客只是记录一下快速使用XXL-JOB的步骤,方便自己日后查看,原文地址

1. 背景

随着系统规模的发展,定时任务数量日益增多,任务也变得越来越复杂,尤其是在分布式环境下,存在多个业务系统,每个业务系统都有定时任务的需求,如果都在自身系统中调度,一方面增加业务系统的复杂度,另一方面也不方便管理,因此需要有一个任务平台对分散的任务进行统一管理调度。

基于目前的情况,任务平台需要支持以下几个方面:

  1. 任务统一管理,提供图形化界面对任务进行配置和调度。
  2. 任务并发控制,同一个任务在同一时间只能允许一个执行。
  3. 任务弹性扩容,可根据繁忙情况动态增减服务器分摊压力,对大任务进行分片处理。
  4. 任务依赖问题,能够处理任务包含子任务的情况,前一个完成后触发子任务执行。
  5. 支持多类型的任务,支持Spring Bean、Shell等。
  6. 任务节点高可用,任务节点异常或者繁忙时能够转移到其他节点执行。
  7. 调度中心高可用,支持集群部署,避免出现单点故障。
  8. 执行状态监控,方便查看任务执行状态,异常情况告警,支持多渠道通知。

发展史:

在这里插入图片描述

定时任务随着技术发展,从单线程调度到多线程调度,从单机部署到集群部署,从独立执行到多任务协同执行。

第一阶段

​ 单线程调度,在Java1.5之前,基于线程的等待(sleep或wait)机制定时执行,需要开发者实现调度逻辑,单个线程(Thread)处理单个任务有些浪费,但是一个线程(Timer)处理多个任务容易因为某个任务繁忙导致其他任务阻塞。

第二阶段

​ 线程池调度,在Java1.5开始提供ScheduledExecutorService调度线程池,调度线程池支持固定的延时和固定间隔模式,对于需要在某天或者某月的时间点执行就不大方便,需要计算时间间隔,转换成启动延时和固定间隔,处理起来比较麻烦。

第三阶段

​ Spring任务调度,Spring简化了任务调度,通过@Scheduled注解支持将某个Bean的方法定时执行,除了支持固定延时和固定间隔模式外,还支持cron表达式,使得定时任务的开发变得极其简单。

第四阶段

​ Quartz任务调度,在任务服务集群部署下,Quartz通过数据库锁,实现任务的调度并发控制,避免同一个任务同时执行的情况。Quartz通过Scheduler提供了任务调度API,开发可以基于此开发自己的任务调度管理平台。

第五阶段

​ 分布式任务平台,提供一个统一的平台,无需再去做和调度相关的开发,业务系统只需要实现具体的任务逻辑,自动注册到任务调度平台,在上面进行相关的配置就完成了定时任务的开发。

解决方案:

现在分布式下任务调度有很多解决方案,可以基于Quartz开发任务管理平台,也可以使用开源的任务调度平台,比如xxl-job,elastic-job。

xxl-job:

大众点评员工徐雪里于2015年发布的分布式任务调度平台,是一个轻量级分布式任务调度框架,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。xxl-job官网地址

elastic-job:

当当开发的弹性分布式任务调度系统,功能丰富强大,采用zookeeper实现分布式协调,实现任务高可用以及分片,并且可以支持云开发,由两个相互独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成。elastic-job官网地址

二者对比:

在这里插入图片描述

2. 简介

XXL-JOB是一个轻量级、分布式、易扩展的调度框架,主要功能是进行任务调度和管理。由中国人许雪里(Xuxueli)开发,因此得名XXL-JOB。xxl-job官网地址

XXL-JOB的主要特点如下

  • 简单易用:XXL-JOB提供了简单的操作界面,用户可以通过Web界面进行任务的管理和调度;
  • 分布式调度:XXL-JOB支持分布式调度,能够在多个服务器上分配任务,提高任务处理的效率和可靠性;
  • 弹性扩容缩容:在任务量增加时,可以动态地增加服务器来处理更多的任务;在任务量减少时,可以减少服务器以节省资源;
  • 任务依赖:XXL-JOB支持设置任务之间的依赖关系,任务可以按照预定的顺序执行;
  • 报警机制:XXL-JOB提供任务执行的报警机制,当任务执行失败或者执行超时时,可以通知任务负责人;
  • 多种任务类型:支持常见的任务类型,如Java、Shell、Python等;
  • 日志记录:XXL-JOB会记录任务的执行日志,方便用户追踪任务的执行情况;
  • 高可用性:通过集群部署,保证系统的高可用性;

xxl-job架构:

在这里插入图片描述

xxl-job通过将调度行为与任务执行解耦的设计思想,形成了两个核心组件:调度中心执行器

  • 调度中心:负责统一管理任务的调度触发逻辑。它提供了一个可视化的操作界面,允许用户创建、编辑、启动、停止任务等。调度中心还负责监控任务的状态,处理任务执行结果,以及在任务执行异常时提供报警机制;
  • 执行器:负责接收调度中心的任务请求,并执行具体的任务逻辑。执行器通常以分布式的方式部署在多个服务器上,可以根据任务量进行弹性伸缩。执行器会向调度中心注册自己,以便调度中心能够发现并分配任务;
  • 数据库:存储任务配置、执行日志、调度记录等数据,保证调度中心与执行器之间的信息同步。支持多种关系型数据库,如MySQL、Oracle等。

3. 快速使用

xxl-job需要分成两个步骤:1.部署调度中心,2.业务系统对接(执行器)。

3.1 准备

下载:

要部署调度中心需要下载xxl-job的源码,将其打成jar包部署

github源码仓库

gitee源码仓库

Plain Text
目录结构
xxl-job-admin:调度中心
xxl-job-core:公共依赖
xxl-job-executor-samples:执行器Sample示例
    :xxl-job-executor-sample-springboot:SpringBoot示例
    :xxl-job-executor-sample-spring:spring示例
    :xxl-job-executor-sample-frameless:无框架示例

中央仓库:

业务系统还需要引入xxl-job的依赖

XML
<!-- http://repo1.maven.org/maven2/com/xuxueli/xxl-job-core/ -->
<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>${最新稳定版本}</version>
</dependency>

环境:

  • Maven3+
  • JDK1.8+
  • MySQL8.0+

3.2 部署调度中心

Windows:

  1. 初始化调度中心数据库:新建数据库xxl-job,执行/xxl-job/doc/db目录下的tables_xxl_job.sql

    • 调度中心支持集群部署,集群情况下各节点务必连接同一个mysql实例;
    • 如果mysql做主从,调度中心集群节点务必强制走主库;
  2. 修改xxl-job-admin中的配置文件

    • 配置文件地址:/xxl-job/xxl-job-admin/src/main/resources/application.properties
    • 根据实际修改,主要修改两部分,一个是数据库配置,另一个是报警邮箱
  3. 构建项目,打包启动

    • 在xxl-job\xxl-job-admin目录下执行mvn clean package,默认打成了jar包,可在pom.xml中修改成war包,这里生成了jar
    • 然后把xxl-job-admin/target目录下生成的jar包启动java -jar xxl-job-admin-*.jar

Linux:

#下载源码
cd /root/
wget https://github.com/xuxueli/xxl-job/archive/v2.0.1.zip
unzip v2.0.1.zip
mv xxl-job-2.0.1 xxl-job

#修改配置文件
vim /root/xxl-job/xxl-job-admin/src/main/resources/application.properties
## 修改mysql、邮件等配置

#编译
cd /root/xxl-job
mvn clean package

# 创建部署目录
mkdir -p /xxl-job
cd /root/xxl-job/xxl-job-admin/target/
cp /root/xxl-job/xxl-job-admin/target/xxl-job-admin-2.0.1.jar /xxl-job/xxl-job-admin-2.0.1.jar


#mysql 数据初始化(用户名和密码为root,数据库编码推荐使用utf8mb4)
mysql -u root -proot -e "source /root/xxl-job/doc/db/tables_xxl_job.sql;"

#启动
nohup java -jar /xxl-job/xxl-job-admin-2.3.1.jar > log.file 2>&1 &

#检查 admin 123456
curl http://localhost:8080/xxl-job-admin

调度中心访问地址:http://localhost:8080/xxl-job-admin (该地址执行器将会使用到,作为回调地址)

默认登录账号 “admin/123456”

3.3 业务系统接入

采用SpringBoot项目接入,可以借鉴示例项目:xxl-job-executor-samples/xxl-job-executor-sample-springboot

3.3.1 引入Maven依赖,同时也必须包含springboot-web依赖
<dependency>
  <groupId>com.xuxueli</groupId>
  <artifactId>xxl-job-core</artifactId>
  <version>2.3.1</version>
</dependency>
3.3.2 配置文件yml配置
server:
  #项目端口号
  port: 8081
logging:
  #日志文件
  config: classpath:logback.xml

xxl:
  job:
    admin:
      # 调度中心部署根地址:如调度中心集群部署存在多个地址则用逗号分隔。
      # 执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调"。这里端口对应xxl-job配置文件中端口
      addresses: http://127.0.0.1:8080/xxl-job-admin
	# 执行器通讯TOKEN [选填]:非空时启用;
	accessToken: 
    #分别配置执行器的名称、ip地址、端口号
    #注意:如果配置多个执行器时,防止端口冲突
    executor:
      appname: executorDemo
      # 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址
      address:
      # 执行器IP [选填]:默认为空表示自动获取IP
      ip:
      # 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999
      port: 9999

      #执行器运行日志文件存储的磁盘位置,需要对该路径拥有读写权限
      logpath: /data/applogs/xxl-job/jobhandler
      #执行器Log文件定期清理功能,指定日志保存天数,日志文件过期自动删除。限制至少保持3天,否则功能不生效;
      #-1表示永不删除
      logretentiondays: -1
3.3.3 执行器组件配置
@Configuration
public class XxlJobConfig {
    @Value("${spring.application.name:}")
    private String springAppName;

    @Value("${xxl.job.admin.addresses}")
    private String adminAddresses;

    @Value("${xxl.job.executor.appname:}")
    private String appName;

    @Value("${xxl.job.executor.ip:}")
    private String ip;

    @Value("${xxl.job.executor.port:9999}")
    private int port;

    @Value("${xxl.job.accessToken:}")
    private String accessToken;

    @Value("${xxl.job.executor.logpath:job-logs}")
    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);
        if (StringUtils.isEmpty(appName)) {
            if (StringUtils.isEmpty(springAppName)) {
                throw new IllegalStateException("missing xxl-job appname config");
            }
            appName = springAppName;
        }
        xxlJobSpringExecutor.setAppName(appName);
        xxlJobSpringExecutor.setIp(ip);
        xxlJobSpringExecutor.setPort(port);
        xxlJobSpringExecutor.setAccessToken(accessToken);
        xxlJobSpringExecutor.setLogPath(logPath);
        xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
		logger.info(">>>>>>>>>>> xxl-job config end.");
        return xxlJobSpringExecutor;
    }
}
3.3.4 定时任务
  • 在2.1.2之前版本每个任务需要单独开发一个Bean,实现IJobHandler接口,并且在类上加@JobHandler注解,这种方式较麻烦,推荐使用下面一种方式

    @JobHandler(value="demoJobHandler")
    @Component
    public class DemoJobHandler extends IJobHandler {
    	@Override
    	public ReturnT<String> execute(String param) throws Exception {
    		XxlJobLogger.log("XXL-JOB, Hello World.");
    		for (int i = 0; i < 5; i++) {
    			XxlJobLogger.log("beat at:" + i);
    			TimeUnit.SECONDS.sleep(2);
    		}
    		return SUCCESS;
    	}
    }
    
  • 在2.1.2或者之后版本可以直接在方法上加@XxlJob来声明任务

    @Component
    public class SampleXxlJob {
        private static Logger logger = LoggerFactory.getLogger(SampleXxlJob.class);
    
        /**
         * 1、简单任务示例(Bean模式)
         */
        @XxlJob("demoJobHandler")
        public ReturnT<String> demoJobHandler(String param) throws Exception {
            XxlJobLogger.log("XXL-JOB, Hello World.");
            for (int i = 0; i < 5; i++) {
                XxlJobLogger.log("beat at:" + i);
                TimeUnit.SECONDS.sleep(2);
            }
            return ReturnT.SUCCESS;
        }
    
        /**
         * 2、分片广播任务
         */
        @XxlJob("shardingJobHandler")
        public ReturnT<String> shardingJobHandler(String param) throws Exception {
            // 分片参数
            ShardingUtil.ShardingVO shardingVO = ShardingUtil.getShardingVo();
            XxlJobLogger.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardingVO.getIndex(), shardingVO.getTotal());
            // 业务逻辑
            for (int i = 0; i < shardingVO.getTotal(); i++) {
                if (i == shardingVO.getIndex()) {
                    XxlJobLogger.log("第 {} 片, 命中分片开始处理", i);
                } else {
                    XxlJobLogger.log("第 {} 片, 忽略", i);
                }
            }
            return ReturnT.SUCCESS;
        }
    }
    
    
3.3.5 配置定时任务
  1. 配置定时任务,需要先配置执行器【执行器管理】,推荐使用自动注册方式,避免集群部署时还需要调整机器地址,添加界面如下(注意appname要和业务系统中配置一致)
    在这里插入图片描述

  2. 添加完执行器后,添加任务【任务管理】,JobHandler要和代码中配置的名称一致,执行器集群部署可以通过配置路由方式来控制执行,xxl-job调度只支持cron表达式。

    在这里插入图片描述

  3. 启动或者执行任务,查询执行日志、注册节点等

  • 18
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
xxl-job是一个分布式任务调度框架,可以用于实现定时任务的调度和执行。在xxl-job中,定时任务的配置和管理主要涉及到三个部分:xxl-job-admin、执行器组件和定时任务的数据处理。 1. xxl-job-admin是xxl-job的管理后台,可以通过调用com.xxl.job.admin.controller.JobApiController.callback接口来设置定时任务。这个接口可以用于添加、修改、删除定时任务,以及启动、停止定时任务的执行。 2. 执行器组件是用于执行定时任务的组件,其中的配置文件地址为/xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/java/com/xxl/job/executor/core/config/XxlJobConfig.java。在这个配置文件中,你可以设置定时任务的一些参数,比如调度线程池大小、任务执行器等。 3. 定时任务的数据处理需要在xxl-job-executor-sample-springboot项目中进行,这是业务代码所在的项目。在这个项目中,你可以使用BEAN模式来设置定时任务。BEAN模式是指通过在类中定义方法并使用@XxlJob注解来标识定时任务,然后在XxlJobConfig.java配置文件中将这个类注册为定时任务。这种方式比较简单,但在官网上没有提供具体的示例。 所以,如果你想使用xxl-job来实现定时任务,你可以先在xxl-job-admin中设置定时任务,然后在执行器组件中配置定时任务的相关参数,最后在xxl-job-executor-sample-springboot项目中使用BEAN模式设置定时任务。这样就能够实现定时任务的调度和执行了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值