返回顶部
首页 > 资讯 > 后端开发 > JAVA >Xxl-job 一文读懂
  • 677
分享到

Xxl-job 一文读懂

java服务器javascript 2023-09-02 08:09:49 677人浏览 泡泡鱼
摘要

目录 1、前言 1.1 运用场景    1.2 什么是定时任务 1.2.1  Java 实现定时任务三大方式 1.2.2  常见开源分布式任务框架 1.2.3 传通定时任务的不足 ·2、Xxl-job 分布式定时任务 2.1 Xxl-job

目录

1、前言

1.1 运用场景   

1.2 什么是定时任务

1.2.1  Java 实现定时任务三大方式

1.2.2  常见开源分布式任务框架

1.2.3 传通定时任务的不足

·2、Xxl-job 分布式定时任务

2.1 Xxl-job 核心组件

 2.2 Xxl-job 优点

3、Xxl-job 实战

3.1、Xxl-job 安装

3.1.1 下载源码

 3.1.2 数据库初始化

3.1.3 XXL-JOB 数据库说明

3.1.4 XXL-JOB 项目介绍

 3.1.5 XXL-JOB 资源配置文件和程序启动入口

3.2、 XXL-JOB 分布式集群部署结构图

 3.3 创建执行器项目

 3.4 配置执行器任务

 3.5 xxl-job 高级配置之路由策略

 3.6 xxl-job 高级配置之父子任务

 3.7 xxl-job 高级配置之动态参数

  3.8 xxl-job 高级配置之分片任务

3.9xxl-job 高级配置之 日志回调

3.10 xxl-job 高级配置之任务生命周期

 3.11 xxl-job 任务配置之运行模式GLUE【Java】 

 3.12 xxl-job 任务配置之运行模式GLUE【Python】 

  3.13 xxl-job 任务配置之运行模式GLUE【Shell】 

 3.14 xxl-job 任务配置之运行模式GLUE【PHP】 

 3.15 xxl-job 任务配置之运行模式GLUE【Node.js】 

 3.16 xxl-job 任务配置之运行模式GLUE【PowerShell】 


1、前言

1.1 运用场景   

  • 数据备份
  • 订单未支付则自动取消
  • 定时爬取数据
  • 定时推送信息
  • 定时发布文章
  • 定时生成报表

1.2 什么是定时任务

        定时任务是指基于给定的时间点,间隔或者给定执行次数自动的执行程序。任务调度室系统的重要组成部分,而对于实时的系统,任务调度直接影响着系统的实时性。任务调度涉及多线程并发、运行时间规则定制与解析、线程池的维护等多项工作。

1.2.1  Java 实现定时任务三大方式

  • JDK自带jdk自带的Timer以及JDK1.5+ 新增的ScheduledExecutorService;
  • Quartz :简单却强大的JAVA作业调度框架
  • Spring Task :可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多;

JDK 自带的定时器实现

  • Timer类
    这个类允许你调度一个java.util.TimerTask任务。主要有以下几个方法:
  1. schedule(TimerTask task, long delay) 延迟 delay 毫秒 执行。
public static void main(String[] args) {        for (int i = 0; i < 10; ++i) {            new Timer("timer - " + i).schedule(new TimerTask() {                @Override                public void run() {                    println(Thread.currentThread().getName() + " run ");                }            }, 1000);        }    }out :timer - 2 run timer - 1 run timer - 0 run timer - 3 run timer - 9 run timer - 4 run timer - 8 run timer - 5 run timer - 6 run timer - 7 run 
  1. schedule(TimerTask task, Date time) 特定时间执行。
public static void main(String[] args) {        for (int i = 0; i < 10; ++i) {            new Timer("timer - " + i).schedule(new TimerTask() {                @Override                public void run() {                    println(Thread.currentThread().getName() + " run ");                }            }, new Date(System.currentTimeMillis() + 2000));        }    }out:timer - 0 run timer - 7 run timer - 6 run timer - 8 run timer - 3 run timer - 5 run timer - 2 run timer - 1 run timer - 4 run timer - 9 run 
  1. schedule(TimerTask task, long delay, long period) 延迟 delay 执行并每隔period 执行一次。
public static void main(String[] args) {        for (int i = 0; i < 10; ++i) {            new Timer("timer - " + i).schedule(new TimerTask() {                @Override                public void run() {                    println(Thread.currentThread().getName() + " run ");                }            }, 2000 , 3000);        }    }out:timer - 0 run timer - 5 run timer - 4 run timer - 8 run timer - 3 run timer - 2 run timer - 1 run timer - 7 run timer - 9 run timer - 6 run timer - 3 run timer - 7 run timer - 5 run timer - 4 run timer - 8 run 

JDK ScheduledExecutorService 接口实现类

        ScheduledExecutorService 是JAVA 1.5 后新增的定时任务接口,主要有以下几个方法。

- ScheduledFuture schedule(Runnable command,long delay, TimeUnit unit);-  ScheduledFuture schedule(Callable callable,long delay, TimeUnit unit);- ScheduledFuture scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnitunit);- ScheduledFuture scheduleWithFixedDelay(Runnable command,long initialDelay,long delay,TimeUnitunit);

        默认实现为ScheduledThreadPoolExecutor 继承了ThreadPoolExecutor 的线程池特性,配合future特性,比Timer更强大。

示例功能代码:

public static void main(String[] args) throws SchedulerException {        ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor)Executors.newScheduledThreadPool(10);        for (int i = 0; i < 10; ++i) {            executor.schedule(new Runnable() {                @Override                public void run() {                    System.out.println(Thread.currentThread().getName() + " run ");                }            } , 2 , TimeUnit.SECONDS);        }        executor.shutdown();    }out:pool-1-thread-2 run pool-1-thread-5 run pool-1-thread-4 run pool-1-thread-3 run pool-1-thread-8 run pool-1-thread-5 run pool-1-thread-7 run pool-1-thread-2 run pool-1-thread-1 run pool-1-thread-6 run 

温馨提示:spring Task内部实现也是基于ScheduledExecutorService 接口。

Quartz 定时器 

Quartz是一个完全由Java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制。Quartz允许开发人员根据时间间隔来调度作业。它实现了作业和触发器的多对多的关系,还能把多个作业与不同的触发器关联。可以动态的添加删除定时任务,另外很好的支撑集群调度

示例功能代码:

Maven 依赖Quartz 定时器jar 包依赖。

                            org.quartz-scheduler            quartz            2.3.0        

创建Quartz 定时器Job类

public class TestJob implements Job{    @Override    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {        println(Thread.currentThread().getName() + " test job begin " + DateUtil.getCurrentTimeStr());    }}

代码测试

public static void main(String[] args) throws InterruptedException, SchedulerException {        Scheduler scheduler = new StdSchedulerFactory().getScheduler();        // 开始        scheduler.start();        // job 唯一标识 test.test-1        JobKey jobKey = new JobKey("test" , "test-1");        JobDetail jobDetail = JobBuilder.newJob(TestJob.class).withIdentity(jobKey).build();        Trigger trigger = TriggerBuilder.newTrigger()                .withIdentity("test" , "test")                // 延迟一秒执行                .startAt(new Date(System.currentTimeMillis() + 1000))                // 每隔一秒执行 并一直重复        .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever())                .build();        scheduler.scheduleJob(jobDetail , trigger);                Thread.sleep(5000);        // 删除job        scheduler.deleteJob(jobKey);    }out :DefaultQuartzScheduler_Worker-1test job begin 2017-06-03 14:30:33DefaultQuartzScheduler_Worker-2test job begin 2017-06-03 14:30:34DefaultQuartzScheduler_Worker-3test job begin 2017-06-03 14:30:35DefaultQuartzScheduler_Worker-4test job begin 2017-06-03 14:30:36DefaultQuartzScheduler_Worker-5test job begin 2017-06-03 14:30:37

Quartz 核心部分

Job:是一个接口,只有一个方法void execute(JobExecutionContext context),开发者实现该接口定义运行任务,JobExecutionContext类提供了调度上下文的各种信息。Job运行时的信息保存在JobDataMap实例中;JobDetail:Quartz在每次执行Job时,都重新创建一个Job实例,所以它不直接接受一个Job的实例,相反它接收一个Job实现类,以便运行时通过newInstance()的反射机制实例化Job。因此需要通过一个类来描述Job的实现类及其它相关的静态信息,如Job名字、描述、关联监听器等信息,JobDetail承担了这一角色。Trigger:是一个类,描述触发Job执行的时间触发规则。主要有SimpleTrigger和CronTrigger这两个子类。当仅需触发一次或者以固定时间间隔周期执行,SimpleTrigger是最适合的选择;而CronTrigger则可以通过Cron表达式定义出各种复杂时间规则的调度方案:如每早晨9:00执行,周一、周三、周五下午5:00执行等;Calendar:org.quartz.Calendar和java.util.Calendar不同,它是一些日历特定时间点的集合(可以简单地将org.quartz.Calendar看作java.util.Calendar的集合——java.util.Calendar代表一个日历时间点,无特殊说明后面的Calendar即指org.quartz.Calendar)。一个Trigger可以和多个Calendar关联,以便排除或包含某些时间点。假设,我们安排每周星期一早上10:00执行任务,但是如果碰到法定的节日,任务则不执行,这时就需要在Trigger触发机制的基础上使用Calendar进行定点排除。Scheduler:代表一个Quartz的独立运行容器,Trigger和JobDetail可以注册到Scheduler中,两者在Scheduler中拥有各自的组及名称,组及名称是Scheduler查找定位容器中某一对象的依据,Trigger的组及名称必须唯一,JobDetail的组和名称也必须唯一(但可以和Trigger的组和名称相同,因为它们是不同类型的)。Scheduler定义了多个接口方法,允许外部通过组及名称访问和控制容器中Trigger和JobDetail。Scheduler可以将Trigger绑定到某一JobDetail中,这样当Trigger触发时,对应的Job就被执行。一个Job可以对应多个Trigger,但一个Trigger只能对应一个Job。可以通过SchedulerFactory创建一个Scheduler实例。Scheduler拥有一个SchedulerContext,它类似于ServletContext,保存着Scheduler上下文信息,Job和Trigger都可以访问SchedulerContext内的信息。SchedulerContext内部通过一个Map,以键值对的方式维护这些上下文数据,SchedulerContext为保存和获取数据提供了多个put()和getXxx()的方法。可以通过Scheduler#getContext()获取对应的SchedulerContext实例;ThreadPool:Scheduler使用一个线程池作为任务运行的基础设施,任务通过共享线程池中的线程提高运行效率。

Spring Task

Spring Task 是 Spring 提供的轻量级定时任务工具,也就意味着不需要再添加第三方依赖了,相比其他第三方类库更加方便易用。

第一步:新建配置类 SpringTaskConfig,并添加 @EnableScheduling注解开启 Spring Task。

@Configuration@EnableSchedulingpublic class SpringTaskConfig {}

可以不新建这个配置类,直接在主类上添加 @EnableScheduling 注解。

@SpringBootApplication@EnableSchedulingpublic class codingmoreSpringtaskApplication {public static void main(String[] args) {SpringApplication.run(CodingmoreSpringtaskApplication.class, args);}}

第二步,新建定时任务类 CronTask,使用 @Scheduled 注解注册 Cron 表达式执行定时任务。

@Slf4j@Componentpublic class CronTask {    @Scheduled(cron = "0/1 * * ? * ?")    public void cron() {        log.info("定时执行,时间{}", DateUtil.now());    }}

启动服务器端,发现每隔一秒钟会打印一次日志,证明 Spring Task 的 cron 表达式形式已经起效了。

默认情况下,@Scheduled 创建的线程池大小为 1,如果想增加线程池大小的话,可以让 SpringTaskConfig 类实现 SchedulinGConfigurer 接口,通过 setPoolSize 增加线程池大小。

@Configuration@EnableSchedulingpublic class SpringTaskConfig implements SchedulingConfigurer {    @Override    public void configureTasks(ScheduledTaskReGIStrar taskRegistrar) {        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();        threadPoolTaskScheduler.setPoolSize(10);        threadPoolTaskScheduler.setThreadNamePrefix("my-scheduled-task-pool-");        threadPoolTaskScheduler.initialize();        taskRegistrar.setTaskScheduler(threadPoolTaskScheduler);    }}

 知识拓展:Spring Task 除了支持 Cron 表达式,还有 fixedRate(固定速率执行)、fixedDelay(固定延迟执行)、initialDelay(初始延迟)三种用法。

@Scheduled(fixedRate = 5000)public void reportCurrentTimeWithFixedRate() {    log.info("Current Thread : {}", Thread.currentThread().getName());    log.info("Fixed Rate Task : The time is now {}", DateUtil.now());}@Scheduled(fixedDelay = 2000)public void reportCurrentTimeWithFixedDelay() {    try {        TimeUnit.SECONDS.sleep(3);        log.info("Fixed Delay Task : The time is now {}",DateUtil.now());    } catch (InterruptedException e) {        e.printStackTrace();    }}@Scheduled(initialDelay = 5000, fixedRate = 5000)public void reportCurrentTimeWithInitialDelay() {    log.info("Fixed Rate Task with Initial Delay : The time is now {}", DateUtil.now());}

1.2.2  常见开源分布式任务框架

  • xxl-job 轻量级分布式任务调度平台
  • Elastic-job 当当开源的分布式调度解决方案
  • Saturn 唯品会开源的分布式任务调度平台
  • light-task-scheduler 阿里员工开源的个人项目
  • Quartz java定时任务的标配

1.2.3 传通定时任务的不足

  • 不支持集群:集群情况下容易造成任务重复问题
  • 不支持失败重试:失败即结束,不支持重试
  • 不支持动态调整:修改任务参数时需要修改代码,并且要重启服务
  • 无报警机制:任务失败后没有提醒功能
  • 无统一管理:没有办法手动关闭或开启任务

·2、Xxl-job 分布式定时任务

Xxl-job是一个开源的,具有丰富的任务管理功能以及高性能,高可用等特点的轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展、开箱即用!!!

 1、将调度行为抽象形成“调度中心”公共平台,而平台自身并不承担业务逻辑,
“调度中心”负责发起调度请求。
2、将任务抽象成分散的JobHandler,交由执行器统一管理,执行器负责接受调度请求
并执行对应的JobHandler中的业务逻辑。
目的: “调度”和“执行任务”可以互相解耦,提供系统整体的稳定性和拓展性。

2.1 Xxl-job 核心组件

  • 调度模块(调度中心): 负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码。调度系统与任务解耦,提高了系统可用性和稳定性,同时调度系统性能不再受限于任务模块; 支持可视化、简单且动态的管理调度信息,包括任务新建,更新,删除,任务报警等,所有上述操作都会实时生效,同时支持监控调度结果以及执行日志,支持执行器Failover。
  • 执行模块(执行器): 负责接收调度请求并执行任务逻辑。任务模块专注于任务的执行等操作,开发和维护更加简单和高效; 接收“调度中心”的执行请求、终止请求和日志请求等。
     

 2.2 Xxl-job 优点

简单:支持通过WEB页面对任务进行CRUD操作,操作简单,一分钟上手;

动态:支持动态修改任务状态、启动/停止任务,以及终止运行中任务,即时生效;

路由策略:执行器集群部署时提供丰富的路由策略,包括:第一个、最后一个、轮询、随机、一致性HASH、最不经常使用、最近最久未使用、故障转移、忙碌转移等;

故障转移:任务路由策略选择”故障转移”情况下,如果执行器集群中某一台机器故障,将会自动Failover切换到一台正常的执行器发送调度请求。

任务超时控制:支持自定义任务超时时间,任务运行超时将会主动中断任务

一致性:“调度中心”通过DB保证集群分布式调度的一致性, 一次任务调度只会触发一次执行

邮件报警:任务失败时支持邮件报警,支持配置多邮件地址群发报警邮件;

任务进度监控:支持实时监控任务进度.
 

3、Xxl-job 实战

3.1、Xxl-job 安装

3.1.1 下载源码

下载项目源码并解压,获取“数据库初始化sql脚本”并执行即可。
git地址:https://github.com/xuxueli/xxl-job
码云地址:https://github.com/xuxueli/xxl-job

官方文档地址:https://www.xuxueli.com/xxl-job/

 3.1.2 数据库初始化

将数据库脚本导入数据库。

3.1.3 XXL-JOB 数据库说明

  1. xxl_job_group :执行器信息表,用于维护任务执行器的信息。
  2. xxl_job_info:调度扩展信息表,主要用于保存调度任务的拓展信息,如:任务分组、任务名称、机器地址等。
  3. xxl_job_lock:任务调度锁.
  4. xxl_job_log:日志表,主要用于保存xxl-job 任务调度的历史信息,如:调度结果,
  5. 执行结果,调度参数等。
  6. xxl_job_log_report:日志报表,存储xxl-job 任务调度的日志报表,会在调度中心报表展示。
  7. xxl_job_logglue:任务GLUE 日志,用于保存GLUE日志的更新变化,支持GLUE版本的回溯。
  8. xxl_job_registry:执行器注册表,用于维护在线的执行器与调度的地址信息。
  9. xxl_job_user:系统的用户表。

3.1.4 XXL-JOB 项目介绍

 3.1.5 XXL-JOB 资源配置文件和程序启动入口

application.properties 配置文件详解

### web 服务端口及其项目名称server.port=8080server.servlet.context-path=/xxl-job-admin### actuator 健康检查management.server.servlet.context-path=/actuatORManagement.health.mail.enabled=false### resources 静态资源配置spring.mvc.servlet.load-on-startup=0spring.mvc.static-path-pattern=/static}
package com.xxl.job.actuator;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class XxlJobActuatorApplication {    public static void main(String[] args) {        SpringApplication.run(XxlJobActuatorApplication.class, args);    }}

第四步:启动执行器项目,并向调度中心注册此执行器,执行器名称为:xxl-job-actuator-sample

打开Xxl-job 调度中心管理端。选择执行器管理/新增

 3.4 配置执行器任务

 在执行器项目:xxl-job-actuator-boot, 添加定时任务DemoJob

package com.xxl.job.actuator.job;import com.xxl.job.core.context.XxlJobHelper;import com.xxl.job.core.handler.annotation.XxlJob;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;import java.util.concurrent.TimeUnit;@Componentpublic class DemoJob {    private static Logger logger = LoggerFactory.getLogger(DemoJob.class);        @XxlJob("demoJobHandler")    public void demoJobHandler() throws Exception {        XxlJobHelper.log("XXL-JOB, 你好.");        for (int i = 0; i < 5; i++) {            XxlJobHelper.log("beat at:" + i);            TimeUnit.SECONDS.sleep(2);        }        // default success    }}

 打开Xxl-job 调度中心管理端。选择任务管理/新增

 

 

点击操作按钮,选择启动,等待一段时间后,查看定时任务执行产生的相关日志信息。

 3.5 xxl-job 高级配置之路由策略

新建任务,在高级配置中路由策略包含如下截图模式:

 向DemoJob 定时任务,添加如下验证路由策略功能代码片段。

      @XxlJob("firstTask")    public ReturnT firstTask(){        XxlJobHelper.log("路由策略模式之:第一个");        return ReturnT.SUCCESS;    }        @XxlJob("lastTask")    public ReturnT lastTask(){        XxlJobHelper.log("路由策略模式之:最后一个");        return ReturnT.SUCCESS;    }        @XxlJob("pollTask")    public ReturnT pollTask(){        XxlJobHelper.log("路由策略模式之:轮训");        return ReturnT.SUCCESS;    }        @XxlJob("hashTask")    public ReturnT hashTask(){        XxlJobHelper.log("路由策略模式之:Hash");        return ReturnT.SUCCESS;    }        @XxlJob("randomTask")    public ReturnT randomTask(){        XxlJobHelper.log("路由策略模式之:随机");        return ReturnT.SUCCESS;    }

 为实现路由策略模式的代码测试,我们需要把xxl-job-actuator-boot执行器项目启动多个实例。多个实例分配如下:

项目名称项目端口内部通信端口
XxlJobActuatorApplication80819999
XxlJobActuatorApplication-808280829998
XxlJobActuatorApplication-808280839997

多个项目实例操作截图:

 

 

验证:同一个执行器是否包含多个服务实例。

高级配置中路由策略功能验证:

 3.6 xxl-job 高级配置之父子任务

父子任务,是指父任务执行后自动调用子任务,完成一种类似于链式的调用。在使用是仅仅需要配置子任务的ID即可。

 新建任务,在高级配置中子任务ID包含如下截图模式:

  向DemoJob 定时任务,添加如下验证父子任务功能代码片段。

    @XxlJob("fatherTask")    public ReturnT fatherTask(){        logger.info("父任务执行");        return ReturnT.SUCCESS;    }        @XxlJob("childTask")    public ReturnT childTask(){        logger.info("子任务执行");        return ReturnT.SUCCESS;    }

  打开Xxl-job 调度中心管理端。选择任务管理/新增父子任务。

 

温馨提示:子任务Id 为xxl-job 为每个任务生成的唯一Id

 3.7 xxl-job 高级配置之动态参数

        xxl-job 支持动态的接受参数进行任务调度,调度器可以传指定参数给具体的任务,
具体任务接受调度参数后,进行相应的业务逻辑处理。

向DemoJob 定时任务,添加如下验证动态参数任务功能代码片段。

     @XxlJob("parameterTask")    public ReturnT parameterTask(){        logger.info("动态参数任务执行");        // 通过XxlJobHelper.getJobParam() 获取参数        String param = XxlJobHelper.getJobParam();        logger.info("参数值为:" + param);        return ReturnT.SUCCESS;    }

  打开Xxl-job 调度中心管理端。选择任务管理/新增动态参数任务。

执行操作,选择仅执行一次,在任务参数中传入当前日期"2022-10-23"

执行器控制台打印相关结果参数:

 JobThread-10-1666540416032,10,main]
23:55:59.254 logback [xxl-job, EmbedServer bizThreadPool-1562433863] INFO  c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job regist JobThread success, jobId:10, handler:com.xxl.job.core.handler.impl.MethodJobHandler@118102ee[class com.xxl.job.actuator.job.DemoJob#parameterTask]
23:55:59.255 logback [xxl-job, JobThread-10-1666540559254] INFO  com.xxl.job.actuator.job.DemoJob - 动态参数任务执行
23:55:59.256 logback [xxl-job, JobThread-10-1666540559254] INFO  com.xxl.job.actuator.job.DemoJob - 参数值为:2022-10-23

  3.8 xxl-job 高级配置之分片任务

        分片任务是指会对所有的执行器广播这个任务,所有的执行器都会接受调用请求,
每个执行器可以根据总分片数及当前执行器的缩影进行相关业务处理。

向DemoJob 定时任务,添加如下验证分片任务功能代码片段。

      @XxlJob("shardTask")    public ReturnT shardTask(){        logger.info("分片任务执行");        // 获取分片信息        //总分片数量        int shardTotal =XxlJobHelper.getShardTotal();        // 当前分片的索引        int shardIndex = XxlJobHelper.getShardIndex();        // 总数据量        int total = 10 *10000;        // 分片平均数据量        int size = total / shardTotal        // 每个 分片的起始值        int startIndex = shardIndex * size +1;        int endIndex = (shardIndex  + 1) *size;        // 处理最后一个分片        if(shardIndex == (shardTotal -1)){            endIndex = total;        }        logger.info("总分片数:{}, 当前分片索引为:{}, 处理数据范围为:{}~{}", shardTotal, shardIndex, startIndex, endIndex);        return ReturnT.SUCCESS;    }

 打开Xxl-job 调度中心管理端。选择任务管理/新增分片任务。

选择新增分片任务,高级配置/路由策略,选择分片广播。

 执行器控制台打印相关结果参数:

00:20:56.301 logback [xxl-job, EmbedServer bizThreadPool-1472487530] INFO  c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job regist JobThread success, jobId:11, handler:com.xxl.job.core.handler.impl.MethodJobHandler@56681eaf[class com.xxl.job.actuator.job.DemoJob#shardTask]
00:20:56.311 logback [xxl-job, JobThread-11-1666542056301] INFO  com.xxl.job.actuator.job.DemoJob - 分片任务执行
00:20:56.311 logback [xxl-job, JobThread-11-1666542056301] INFO  com.xxl.job.actuator.job.DemoJob - 总分片数:1, 当前分片索引为:0, 处理数据范围为:1~100000

3.9xxl-job 高级配置之 日志回调

        日志回调是指执行器在执行任务时可以将执行日志传递给调度中心,即使任务没有执行完成,调度中心也可以看到回调的调度日志内容,便于开发者能够更细化的分析任务的执行情况。

向DemoJob 定时任务,添加如下验证任务日志回调功能代码片段。

    @XxlJob(value = "logCallBackTask")    public ReturnT logCallBackTask() throws InterruptedException {        logger.info("任务日志回调执行");        XxlJobHelper.log("当前日志执行至{}行", 143);        Thread.sleep(3000);        XxlJobHelper.log("当前日志执行至{}行", 145);        Thread.sleep(3000);        XxlJobHelper.log("当前日志执行至{}行", 147);        return ReturnT.SUCCESS;    }

  打开Xxl-job 调度中心管理端。选择任务管理/新增任务日志回调任务。

根据任务ID,将页面切换至调度日志,点击查询执行日志信息。

 

3.10 xxl-job 高级配置之任务生命周期

        xxl-job 支持在任务调用时,第一次调用时先执行指定方法,然后在执行具体的任务,
当执行器停止时会执行指定方法,这就是xxl-job 任务的生命周期。

向DemoJob 定时任务,添加如下验证任务生命周期功能代码片段。

     @XxlJob(value = "lifeCycleTask", init = "init", destroy = "destroy")    public ReturnT lifeCycleTask(){        logger.info("任务生命周期执行");        return ReturnT.SUCCESS;    }    public void init(){        logger.info("任务初始化方法");    }    public void destroy() {        logger.info("任务销毁方法");    }

 打开Xxl-job 调度中心管理端。选择任务管理/新增任务生命周期任务。

 执行器控制台打印相关结果参数:

 

 00:30:30.055 logback [xxl-job, JobThread-12-1666542630055] INFO  com.xxl.job.actuator.job.DemoJob - 任务初始化方法
00:30:30.063 logback [xxl-job, JobThread-12-1666542630055] INFO  com.xxl.job.actuator.job.DemoJob - 任务生命周期执行
00:32:03.274 logback [xxl-job, JobThread-12-1666542630055] INFO  com.xxl.job.actuator.job.DemoJob - 任务销毁方法

 3.11 xxl-job 任务配置之运行模式GLUE【Java】 

        任务以源码方式维护在调度中心,支持通过Web IDE在线更新,实时编译和生效,因此不需要指定JobHandler。

打开Xxl-job 调度中心管理端。选择任务管理/新增GLUE【Java】任务。

开发任务代码:

选中指定任务,点击该任务右侧“GLUE”按钮,将会前往GLUE任务的Web IDE界面,在该界面支持对任务代码进行开发(也可以在IDE中开发完成后,复制粘贴到编辑中)。

版本回溯功能(支持30个版本的版本回溯):在GLUE任务的Web IDE界面,选择右上角下拉框“版本回溯”,会列出该GLUE的更新历史,选择相应版本即可显示该版本代码,保存后GLUE代码即回退到对应的历史版本;

查看任务调度中心,查看GLUE【Java】日志记录

 3.12 xxl-job 任务配置之运行模式GLUE【python】 

温馨提示:请先确认调度中心服务器是否安装Python环境,我本地调度中心服务器安装的是python3.

新建的任务进行参数配置,运行模式选中 “GLUE模式(Python)”; 

 

开发任务Python代码:

选中指定任务,点击该任务右侧“GLUE”按钮,将会前往GLUE任务的Web IDE界面,在该界面支持对任务代码进行开发(也可以在IDE中开发完成后,复制粘贴到编辑中)

#!/usr/bin/python3import timeimport ioimport syssys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') print ("xxl-job: hello python")print ("脚本位置:", sys.argv[0])print ("任务参数:", sys.argv[1])print ("Good bye!")​

查看任务调度中心,查看GLUE【Python】日志记录 

  3.13 xxl-job 任务配置之运行模式GLUE【shell】 

 新建的任务进行参数配置,运行模式选中 “GLUE模式(Shell)”;

 

开发任务Shell代码:

选中指定任务,点击该任务右侧“GLUE”按钮,将会前往GLUE任务的Web IDE界面,在该界面支持对任务代码进行开发(也可以在IDE中开发完成后,复制粘贴到编辑中)

#!/bin/bashecho "xxl-job: hello shell"echo "脚本位置:$0"echo "任务参数:$1"echo "分片序号 = $2"echo "分片总数 = $3"echo "Good bye!"exit 0

 查看任务调度中心,查看GLUE【Shell】日志记录 

产生上述错误的原因:调度中心服务器是windows 系统,Bash 命令是linux 系统,解决此问题的办法:第一种方法:将调度中心的系统切换为Linux 系统, 第二种方法:Windows系统中安装Cygwin.

 3.14 xxl-job 任务配置之运行模式GLUE【PHP】 

由于本机缺失环境,此章节不做讲解

 3.15 xxl-job 任务配置之运行模式GLUE【node.js】 

由于本机缺失环境,此章节不做讲解

 3.16 xxl-job 任务配置之运行模式GLUE【PowerShell】 

由于本机缺失环境,此章节不做讲解

来源地址:https://blog.csdn.net/zhouzhiwengang/article/details/127463853

--结束END--

本文标题: Xxl-job 一文读懂

本文链接: https://lsjlt.com/news/390218.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Xxl-job 一文读懂
    目录 1、前言 1.1 运用场景    1.2 什么是定时任务 1.2.1  Java 实现定时任务三大方式 1.2.2  常见开源分布式任务框架 1.2.3 传通定时任务的不足 ·2、Xxl-job 分布式定时任务 2.1 Xxl-job...
    99+
    2023-09-02
    java 服务器 javascript
  • 一文读懂JNDI
    JNDI(Java Naming and Directory Interface)是Java提供的一种用于访问命名和目录服务的API...
    99+
    2023-09-20
    JNDI
  • 一文读懂IPSec
    IPSec(Internet Protocol Security)是一种用于保护网络通信安全的协议。它通过加密和认证机制,确保数据在...
    99+
    2023-09-21
    IPSec
  • 一文读懂ActivityThread
    ActivityThread是Android系统中的一个重要组件,它负责管理和调度应用程序中的Activity。在Android应用...
    99+
    2023-09-13
    ActivityThread
  • 一文读懂 MySQL 锁
    1 MySQL 锁简介 1.1 什么是锁 锁是计算机用以协调多个进程间并发访问同一共享资源的一种机制。MySQL中为了保证数据访问的一致性与有效性等功能,实现了锁机制,MySQL中的锁是在服务器层或者存储引擎层实现的。 1.2 锁用来解决什...
    99+
    2023-08-16
    mysql 数据库 java
  • 一文读懂EVPN技术
    EVPN(Ethernet Virtual Private Network)是一种新兴的以太网虚拟专用网络技术,可以提供灵活、可靠、...
    99+
    2023-09-20
    EVPN
  • 一文读懂MySQL 表分区
    目录1. 什么是表分区2. 分区的两种方式2.1 水平切分2.2 垂直切分3. 为什么需要表分区4. 分区实践4.1 RANGE 分区4.2 LIST 分区4.3 HASH 分区4....
    99+
    2024-04-02
  • 一文读懂 Python 装饰器
    Python 是一种对新手很友好的语言。但是,它也有很多较难掌握的高级功能,比如装饰器(decorator)。很多初学者一直不理解装饰器及其工作原理,在这篇文章中,我们将介绍装饰器的来龙去脉。在 Python 中,函数是一种非常灵活的结构,...
    99+
    2023-05-14
    Python 装饰器
  • 一文读懂C++ 虚函数 virtual
    探讨 C++ 虚函数 virtual 有无虚函数的对比 C++ 中的虚函数用于解决动态多态问题,虚函数的作用是允许在派生类中重新定义与积累同名的函数,并且可以通过基类指针或引用来访问...
    99+
    2024-04-02
  • 一文读懂 MySQL 中的索引
    文章目录 1. 索引概述1.1 索引概述1.2 优点1.3 缺点1.6 常见索引概念1.6.1 聚簇索引1.6.2 二级索引(辅助索引、非聚簇索引)1.6.3 联合索引 1.8 MyISAM索引的原理1.9 MyISAM 与 ...
    99+
    2023-08-16
    mysql android 数据库
  • 一文读懂Android Kotlin的数据流
    目录一、Android分层架构二、ViewModel + LiveData2.1 LiveData 特性观察者的回调永远发生在主线程仅持有单个且最新数据自动取消订阅提供「可读可写」和...
    99+
    2024-04-02
  • 一文带你读懂Java IO复用
    本篇文章为大家展示了一文带你读懂Java IO复用,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。对于服务器的并发处理能力,我们需要的是:每一毫秒服务器都能及时处理这一毫秒内收到的数百个不同TCP连接...
    99+
    2023-05-31
    java io复用 ava
  • 一文搞懂MySQL脏读,幻读和不可重复读
    目录MySQL 中事务的隔离1.READ UNCOMMITTED2.READ COMMITTED3.REPEATABLE READ4.SERIALIZABLE前置知识1.事务相关的常...
    99+
    2024-04-02
  • 一文读懂navicat for mysql基础知识
    目录一、数据库的操作二、数据类型三、备份和恢复三、操作动作四、高级五、知识补充一、数据库的操作 新建数据库 打开数据库 右键或者双击就可以了。 删除数据库 右键>删除数据库 修改数据库 右键>数据库属性...
    99+
    2022-05-13
    navicat mysql基础 navicat for mysql
  • 一篇文章读懂nginx的gzip_static模块
    Nginx支持静态和动态两种包体gzip压缩方式,分别对应模块ngx_http_gzip_static,ngx_http_gzip。 我们知道gzip是CPU密集型的应用,实时动态压...
    99+
    2024-04-02
  • 一篇文章读懂nginx的gzip功能
    目录前言语义:拓扑:仿真:验证:gzip_proxied的参数解析:小结:总结前言 HTTP中包体【body】压缩协商对应的头字段为Accept-Encoding/Content-E...
    99+
    2024-04-02
  • 一文读懂C++中的函数对象
    这篇文章给大家介绍一文读懂C++中的函数对象,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。如果一个类将()运算符重载为成员函数,这个类就称为函数对象类,这个类的对象就是函数对象。函数对象是一个对象,但是使用的形式看起来...
    99+
    2023-06-06
  • 什么是CDN一文带您读懂CDN
    CDN(Content Delivery Network)是一种基于网络的技术,用于提高网站的访问速度和性能。CDN通过将网站的静态...
    99+
    2023-09-23
    CDN
  • 【Servlet篇】一文带你读懂Request对象
    文章目录 1. 前言 2. Request 对象 2.1 Request 继承体系 2.2 Request 获取请求参数 1. 获取请求...
    99+
    2023-10-22
    servlet java tomcat
  • 一文读懂层次聚类(Python代码)
    首先要说,聚类属于机器学习的无监督学习,而且也分很多种方法,比如大家熟知的有K-means。层次聚类也是聚类中的一种,也很常用。下面我先简单回顾一下K-means的基本原理,然后慢慢引出层次聚类的定义和分层步骤,这样更有助于大家理解。层次聚...
    99+
    2023-05-14
    代码 Python 层次聚类
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作