第四章 分布式任务调度笔记

本文深入解析Quartz、Spring Task、Elastic-Job和XXL-Job等任务调度框架的使用方法,涵盖基本用法、分布式调度特性及其实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码git地址:https://gitee.com/hankin_chj/schedule-job-platform.git

一、任务调度的基本用法

1、Quartz Scheduler开源框架

Quartz是开源任务调度框架中的翘首,是java业务界事实上的任务调度标准。 Quartz提供了强大任务调度机制,而且使用简单。Quartz允许开发人员灵活地定义触发器的调度时间表,并可以对触发器和任务进行关联映射。此外Quartz提供了调度运行环境的持久化机制,可以保存并恢复调度现场,即使系统因故障关闭,任务调度现场数据并不会丢失。此外Quartz还提供了组件式的侦听器、各种插件、线程池等功能。

2、Quartz的核心元素

  • Quartz主要涉及以下元素概念: 
  • scheduler:任务调度器;
  • trigger:触发器,用于定义任务调度时间规则;
  • job:任务,即被调度的任务;
  • misfire:错过的,指本来应该被执行但实际没有被执行的任务调度其中trigger和job是任务调度的元数据,scheduler是实际执行调度的控制器。
  • trigger是用于定义调度时间的元素,即按照什么时间规则去执行任务。Quartz中主要提供了四种类型的trigger:SimpleTrigger,CronTirgger,DateIntervalTrigger和NthIncludedDayTrigger。这四种trigger可以满足企业应用中的绝大部分需求。我们将在企业应用一节中进一步讨论四种trigger的功能。
  • job用于表示被调度的任务。主要有两种类型的 job:无状态的(stateless)和有状态的(stateful)。对于同一个trigger来说,有状态的job不能被并行执行,只有上一次触发的任务被执行完之后,才能触发下一次执行。Job主要有两种属性:volatility和durability,其中volatility表示任务是否被持久化到数据库存储,而durability表示在没有trigger关联的时候任务是否被保留。两者都是在值为true的时候任务被持久化或保留。

一个job可以被多个trigger关联,但是一个trigger只能关联一个job。 scheduler由scheduler工厂创建:DirectSchedulerFactory或者StdSchedulerFactory。 一般使用StdSchedulerFactory工厂较多。Scheduler主要有三种:RemoteMBeanScheduler,RemoteScheduler和StdScheduler,最常用的为StdScheduler。

核心元素间关系如下图:

 

3、Quartz的线程

在Quartz中,有两类线程,Scheduler调度线程和任务执行线程,其中任务执行线程通常使用一个线程池维护一组线程。

 

Scheduler调度线程主要有两个:执行常规调度的线程,和执行misfired trigger的线程。常规调度线程轮询存储的所有trigger,如果有需要触发的trigger,即到达了下一次触发的时间,则从任务执行线程池获取一个空闲线程,执行与该trigger关联的任务。Misfire线程是扫描所有的trigger,查看是否有misfired trigger,如果有的话根据misfire的策略分别处理。

4数据存储

Quartz中的trigger和job需要存储下来才能被使用。Quartz中有两种存储方式:RAMJobStore、JobStoreSupport,其中RAMJobStore是将 trigger和job存储在内存中, 而JobStoreSupport是基 jdbc将trigger 和job存储到数据库中。RAMJobStore的存取速度非常快,但是由于其在系统被停止后所有的数据都会丢失, 所以在通常应用中,都是使用JobStoreSupport。

在Quartz中,JobStoreSupport使用一个驱动代理来操作trigger和job的数据存储:StdJDBCDelegate。StdJDBCDelegate实现了大部分基于标准JDBC的功能接口,但是对于各种数据库来说,需要根据其具体实现的特点做某些特殊处理,因此各种数据库需要扩展StdJDBCDelegate以实现这些特殊处理。Quartz已经自带了一些数据库的扩展实现,可以直接使用。

 

5Quartz的用法

5.1、配置目标任务

使用Spring Quartz实现Job任务有两种方式,一种是实现org.quartz.Job接口,这个不推荐。另一种不需要继承,只需要在配置文件中定义MethodInvokingJobDetailFactoryBean,并指定它的targetObject属性为Job任务类,targetMethod属性为任务方法就可以了。targetObject 属性指定目标对象。

@Configuration
public class QuartzConfig {
    /**
     * 耦合业务
     * TODO 将调度环境信息传递给业务方法,如:调度时间,批次等
     */
    @Bean(name = "businessJobDetail")
    public JobDetailFactoryBean businessJobDetail() {
        JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
        //业务bean是多例的还是单例的? 多例
        jobDetailFactoryBean.setJobClass(BusinessJob.class);
        //TODO 将参数封装传递给job
        JobDataMap jobDataMap =new JobDataMap();
        jobDataMap.put("time",System.currentTimeMillis());
        jobDetailFactoryBean.setJobDataAsMap(jobDataMap);
        return  jobDetailFactoryBean;
    }
    //TODO 普通业务类
    @Bean(name = "serviceBeanDetail")
    public MethodInvokingJobDetailFactoryBean serviceBeanDetail(XXXService serviceBean) {//业务bean,单例的
        MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
        //TODO  是否并发执行
        jobDetail.setConcurrent(false);
        // TODO 需要执行的实体bean
        jobDetail.setTargetObject(serviceBean);
        // TODO 需要执行的方法
        jobDetail.setTargetMethod("business");
        return jobDetail;
    }

5.2、配置触发器

//TODO 简单触发器
@Bean(name = "simpleTrigger")
public SimpleTriggerFactoryBean simpleTrigger(JobDetail businessJobDetail) {
    SimpleTriggerFactoryBean trigger = new SimpleTriggerFactoryBean();
    trigger.setJobDetail(businessJobDetail);
    // TODO 设置任务启动延迟
    trigger.setStartDelay(0);
    //TODO  每5秒执行一次
    trigger.setRepeatInterval(3000);
    return trigger;
}
//TODO cron触发器
@Bean(name = "cronTrigger")
public CronTriggerFactoryBean cronTrigger(JobDetail serviceBeanDetail) {
    CronTriggerFactoryBean triggerFactoryBean = new CronTriggerFactoryBean();
    triggerFactoryBean.setJobDetail(serviceBeanDetail);
    triggerFactoryBean.setCronExpression("0/6 * * * * ?");
    return triggerFactoryBean;
}

5.3配置调度工厂

//TODO 调度工厂,将所有的触发器引入
@Bean(name = "scheduler")
public SchedulerFactoryBean schedulerFactory(Trigger simpleTrigger, Trigger cronTrigger) {
    SchedulerFactoryBean bean = new SchedulerFactoryBean();
    //TODO 延时启动,应用启动1秒后
    bean.setStartupDelay(1);
    //TODO 注册触发器
    bean.setTriggers(simpleTrigger,cronTrigger);
    return bean;
}

5.4、具体某个定时任务调度的业务实现

public class BusinessJob implements Job{
    int i = 0;
    public void execute(JobExecutionContext context) throws JobExecutionException {
        JobDataMap dataMap = context.getJobDetail().getJobDataMap();
        String name = dataMap.get("time").toString();
        business(name);
   }
    //重型任务,1000W数据统计,把任务敲碎 -- E-job
    private void business(String time){
        i++;
        System.out.println("BusinessJob start --- time:"+time+", thread:" + Thread.currentThread().getName() );
    }
}

到此,整个配置就完成了。

6spring task调度器用法

Spring从3.0开始增加了自己的任务调度器,它是通过扩展java.util.concurrent包下面的类来实现的,它也使用Cron表达式。使用spring task非常简单,只需要给定时任务类添加@Component 注解,给任务方法添加@Scheduled(cron = "0/5 * * * * ?")注解,并让 Spring 扫描到该类即可。

如果定时任务很多,可以配置executor线程池,这里executor的含义和java.util.concurrent.Executor是一样的,pool-size的大小官方推荐为5~10。scheduler pool-size是ScheduledExecutorService线程池。

6.1、定时任务线程池配置:

/**
 * 没有此配置,则schedule为单线程串行执行
 */
@Configuration
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer {
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
    }
    //配置线程池---触发器和任务共用的
    @Bean(destroyMethod="shutdown")
    public Executor taskExecutor() {
        return Executors.newScheduledThreadPool(10);
    }
}

6.2、定时任务实现代码:

具体定时任务配置通过@EnableScheduling与@Scheduled(cron = "0/5 * *  * * ?")来实现

@Component
@EnableScheduling
public class TaskConfig {
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
    @Scheduled(fixedDelayString = "5000") //单机
    public void getTask1() {
        //TODO 竞争锁逻辑代码 .....
        System.out.println("任务1,当前时间:" + dateFormat.format(new Date())+",线程号:"
                +Thread.currentThread().getName());
        throw new RuntimeException("xxxxx");
    }
    @Scheduled(cron = "0/5 * *  * * ?")
    public void getTask2() {
        System.out.println("任务2,当前时间:" + dateFormat.format(new Date())+",线程号:"
                +Thread.currentThread().getName());
    }
}

7、cron表达式:

 

  • *:表示匹配该域的任意值。
  • ?:只能用在DayofMonth和DayofWeek两个域,表示匹配域的任意值。
  • -:表示范围
  • /:表示起始时间开始触发,然后每隔固定时间触发一次
  • ,:表示列出枚举值值。
  • L:表示最后,只能出现在DayofWeek和DayofMonth域
  • W: 表示有效工作日(周一到周五),只能出现在DayofMonth域
  • LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。
  • #:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。

二、分布式任务调度

在系统需要运行大量耗时定时任务的场景下,单使用类似Quartz或者spring task等定时任务框架无法满足对并发处理性能、监控管理及运维拓展的要求。此时,定时任务主要面临以下几个新问题: l

  • 多节点重复执行某一任务;
  • 大量的任务管理困难;
  • 某些大型任务耗时超长,需要切分给多台机器并行执行;

简单地说,如果仅仅面向解决第一个问题,我们可以借助分布式锁,来规避节点的执行难题(有兴趣的可参考分布式锁的使用)。

下面我们主要介绍elastic-job和xxl-job这两个框架

共同点: E-Job和X-job都有广泛的用户基础和完整的技术文档,都能满足定时任务的基本功能需求。

不同点:

X-Job侧重的业务实现的简单和管理的方便,学习成本简单,失败策略和路由策略丰富。推荐使用在“用户基数相对少,服务器数量在一定范围内,任务数量多”的情景下使用。

E-Job关注的是数据,增加了弹性扩容和数据分片的思路,以便于更大限度的利用分布式服务器的资源。但是学习成本相对高些, 推荐在“数据量庞大,且部署服务器数量较多”时使用。

1、E-Job分布式调度

Elastic-Job是一个分布式调度解决方案,由两个相互独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成。Elastic-Job-Lite定位为轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务。基于quartz定时任务框架为基础的,因此具备quartz的大部分功能使用zookeeper做协调,调度中心,更加轻量级。

支持任务的分片、支持弹性扩容,可以水平扩展,当任务再次运行时,会检查当前的服务器数量,重新分片,分片结束之后才会继续执行任务失效转移,容错处理,当一台调度服务器宕机或者跟zookeeper断开连接之后,会立即停止作业,然后再去寻找其他空闲的调度服务器,来运行剩余的任务提供运维界面,可以管理作业和注册中心。

我们主要介绍 Elastic-Job-Lite的去中心化解决方案。

1.2使用场景

当今互联网项目大多为微服务,单模块可能在两个实例以上的数量,定时器就会出现多实例同时执行的情况。同时,我们的某些 任务可能还存在过大,需要切片来加速执行等需求,归结如下: ·

  • 分布式调度协调;
  • 弹性扩容缩容;
  • 失效转移;
  • 错过执行作业重触发;
  • 作业分片一致性,保证同一分片在分布式环境中仅一个执行实例;
  • 自诊断并修复分布式不稳定造成的问题;
  • 支持并行调度;
  • 支持作业生命周期操作;
  • 丰富的作业类型;
  • Spring 整合以及命名空间提供;

运维平台Elastic-Job-Lite以其简单易用,无中心化方式,非常适合用来简单整合普通业务。

1.3、添加依赖

<!-- 注意elastic在maven默认的中央仓库里面没有,需要单独配置拉去 -->
<dependency>
    <groupId>com.github.yinjihuan</groupId>
    <artifactId>elastic-job-spring-boot-starter</artifactId>
    <version>1.0.2</version>
</dependency>

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

1.4、配置

ps: 需要zookeeper支持,请提前搭建好,配置application.properties加入以下配置:

# zk注册中心
elastic.job.zk.serverLists=127.0.0.1:2181
elastic.job.zk.namespace=hankin_elastic7
spring.main.allow-bean-definition-overriding=true
server.port=8283

配置很简单,只需要加入zk注册中心地址和job名称空间即可。

1.5定时器实现方法编写

例如实现一个简单的定时任务:

@ElasticJobConf(name = "MySimpleJob",cron = "0/5 * * * * ?"
      ,shardingItemParameters = "0=beijing|shenzhen|tianjin,1=shanghai",shardingTotalCount = 2
      ,listener = "com.chj.handle.MessageElasticJobListener"
      ,jobExceptionHandler = "com.chj.handle.CustomJobExceptionHandler"
)
public class MySimpleJob implements SimpleJob {
   @Autowired
   private MyBusiness myBusiness;
   public void execute(ShardingContext context) {
      System.out.println("MySimpleJob,当前分片:"+context.getShardingParameter());
      //TODO 当前起始 context.getShardingParameter(),回返切片信息beijing
      String sql = myBusiness.getSql(context.getShardingParameter());
      myBusiness.process(sql);
   }
}

作业监听器需要实现ElasticJobListener 接口:

public class MessageElasticJobListener implements ElasticJobListener {
    @Override
    public void beforeJobExecuted(ShardingContexts shardingContexts) {
        String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        String msg = date + " 【任务开始执行-" + shardingContexts.getJobName() + "】";
        System.out.println("给管理发邮件:"+msg);
    }
    @Override
    public void afterJobExecuted(ShardingContexts shardingContexts) {
       String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        String msg = date + " 【任务执行结束-" + shardingContexts.getJobName() + "】" ;
        System.out.println("给管理发邮件:"+msg);
    }
}

自定义异常处理需要实现JobExceptionHandler接口

public class CustomJobExceptionHandler implements JobExceptionHandler {
    private Logger logger = LoggerFactory.getLogger(CustomJobExceptionHandler.class);
    @Override
    public void handleException(String jobName, Throwable cause) {
        logger.error(String.format("Job '%s' exception occur in job processing", jobName), cause);
        System.out.println("给管理发邮件:【"+jobName+"】任务异常。" + cause.getMessage());
    }
}

具体执行的业务方法:

@Service
public class MyBusiness {
   private String sql_tpl = "select * from xxx where param = %s";
   public String getSql(String param){
      return String.format(sql_tpl,param);
   }
   //index指示,现在跑的是第几片total指示,总共有几片
   public void process(String sql) {
      //分片任务
      System.out.println("当前执行sql:"+sql);
   }
}

1.6定时任务的几种实现方式

Elastic-job总共提供了三种类型的定时任务:Simple类型定时任务、Dataflow类型定时任务和Script类型定时任务。其中Script类型作业意为脚本类型作业,支持shell,python和perl等所有类型脚本,应用得不太多。

SimpleJob需要实现SimpleJob接口,是未经过任何封装的定时任务简单实现,与quartz原生接口相似。Dataflow类型的定时任务主要用于处理数据流,需实现DataflowJob接口。该接口可以提供2个方法可供覆盖,分别用于抓取(fetchData)和处理(processData)数据。

推荐使用ElasticJobConf注解方:

@ElasticJobConf(name = "EnjoySimpleJob",cron = "0/5 * * * * ?"

,shardingItemParameters = "0=beijing,1=shanghai",

shardingTotalCount = 2 ,

listener = "com.enjoy.handle.MessageElasticJobListener" ,

jobExceptionHandler = "com.chj.handle.CustomJobExceptionHandler

)

ElasticJobConf 的常用的参数释义如下

cron:cron表达式,用于配置作业触发时间;

sharding-total-count 作业分片总数;

sharding-item-parameters:分片序列号和参数用等号分隔,多个键值对用逗号分隔 分片序列号从 0 开始,不可大于或等于作业分片总数 如:0=a,1=b,2=c。

job-parameter:作业自定义参数,可以配置多个相同的作业,但是用不同的参数作为不同的调度实例

Misfire:是否开启错过任务重新执行。

Listener:任务开始和结束时,自定义的处理功能。

jobExceptionHandler:任务异常时,自定义的处理。

1.7、任务启动

对于springboot来说,使用EnableElasticJob标注ElasticJob即可。

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

2、X-Job分布式调度

XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码,并接入多家公司线上产品线,开箱即用。与 E-Job走无中心化方式不同,XXL-JOB是中心集权方式。

2.1、使用场景

基于spring,quartz,netty开源定时任务框架,解决的问题是不用每一个job-client都需要集成quartz,管 理 cron 配置,尤其 job 很多的时候当容器启动会执行一堆 job,影响启动速度。 原理简单而言就是由 job 配置中心管理通过 quartz 控制客户端 job 触发时机,然后通过 netty rpc 调用执行客户端的具体 实现。这样中心化的方式可以极大改善 job 的管理成本,还可以配置集群。

下面是其全景图:

 

xxl-job的官方文档非常详细,可以到这里查看:https://www.xuxueli.com/xxl-job/#/

本文,我们主要讲解一个其基本的搭建与使用流

2.2、部署调度中心

作为中心化的调度平台,xxl的调度中心当然是核心中的核心。其作用:统一管理任务调度平台上调度任务,负责触发调度执行,并且提供任务管理平台。

你可以 github 下载:https://github.com/xuxueli/xxl-job

下载好代码包后,第一步执行 doc 中的 db 脚本,创建好数据库表。

然后更改调度中心配置文件地址:/xxl-job/xxl-job-admin/src/main/resources/xxl-job-admin.properties

启动:直接启动 XxlJobAdminApplication 即可

### web
server.port=8080
server.context-path=/xxl-job-admin
### resources
spring.mvc.static-path-pattern=/static/**
spring.resources.static-locations=classpath:/static/
### freemarker
spring.freemarker.templateLoaderPath=classpath:/templates/
spring.freemarker.suffix=.ftl
spring.freemarker.charset=UTF-8
spring.freemarker.request-context-attribute=request
spring.freemarker.settings.number_format=0.##########
### mybatis
mybatis.mapper-locations=classpath:/mybatis-mapper/*Mapper.xml
### xxl-job, datasource
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxljob?Unicode=true&characterEncoding=UTF-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource
spring.datasource.tomcat.max-wait=10000
spring.datasource.tomcat.max-active=30
spring.datasource.tomcat.test-on-borrow=true
spring.datasource.tomcat.validation-query=SELECT 1
spring.datasource.tomcat.validation-interval=30000
### xxl-job email
spring.mail.host=smtp.qq.com
spring.mail.port=25
spring.mail.username=xxx@qq.com
spring.mail.password=xxx
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
### xxl-job login
xxl.job.login.username=admin
xxl.job.login.password=123456
### xxl-job, access token
xxl.job.accessToken=
### xxl-job, i18n (default empty as chinese, "en" as english)
xxl.job.i18n=

2.3、调度中心集群

在生产环境中,需要提升调度系统容灾和可用性,调度中心支持集群部署,只需要多台部署连接同一套数据库即可。

  • DB 配置保持一致;
  • 登陆账号配置保持一致;
  • 集群机器时钟保持一致(单机集群忽视);

建议:推荐通过nginx为调度中心集群做负载均衡,分配域名。

调度中心访问、执行器回调配置、调用 API 服务等操作均通过该域名进行。

2.4、部署执行项目

执行器就是我们的业务系统,负责接收“调度中心”的调度并执行业务任务;下面简介集成步骤:

步骤1:引入 xxl-job-core的依赖

<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>2.0.2</version>
</dependency>

步骤2执行器配置

在application.properties下的配置信息信息如下:

### 调度器的地址----- 发消息
xxl.job.admin.addresses=http://localhost:8080/xxl-job-admin
### 当前执行器的标识名称,同一个名字的执行器构成集群
xxl.job.executor.appname=xxl-job
# 执行器与调度器通信的ip / port
xxl.job.executor.ip=
xxl.job.executor.port=9993
### job-job, access token
xxl.job.accessToken=
### job-job log path
xxl.job.executor.logpath=/logs/xxl/job
### job-job log retention days
xxl.job.executor.logretentiondays=-1
server.port=8283

### 调度中心部署跟地址 [选填]:

如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注 册"和"任务结果回调";为空则关闭自动注册;xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin

### 执行器 AppName [选填]:

执行器心跳注册分组依据;为空则关闭自动注册 xxl.job.executor.appname= xxl-job

### 执行器 IP [选填]:

默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于"执行器注册"和"调度中心请求并触发任务";xxl.job.executor.ip=

### 执行器端口号 [选填]:

小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;xxl.job.executor.port=9999

### 执行器通讯 TOKEN [选填]:非空时启用;xxl.job.accessToken=

### 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;

xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler

### 执行器日志保存天数 [选填] :值大于 3 时生效,启用执行器 Log 文件定期清理功能,否则不生效; xxl.job.executor.logretentiondays=-1

步骤3:执行器组件配置

需要将上面的执行器各项参数,配置到 XxlJobSpringExecutor 组件中,创建如下

@Configuration
@ComponentScan(basePackages = "com.xxl.job.executor.service.jobhandler")
public class XxlConfig {
    private Logger logger = LoggerFactory.getLogger(XxlConfig.class);
    @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}")
    private int port;
    @Value("${xxl.job.accessToken}")
    private String accessToken;
    @Value("${xxl.job.executor.logpath}")
    private String logPath;
    @Value("${xxl.job.executor.logretentiondays}")
    private int logRetentionDays;
    @Bean(initMethod = "start", destroyMethod = "destroy")
    public XxlJobSpringExecutor xxlJobExecutor() {
        logger.info(">>>>>>>>>>> job-job config init.");
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
        xxlJobSpringExecutor.setAppName(appName);
        xxlJobSpringExecutor.setIp(ip);
        xxlJobSpringExecutor.setPort(port);
        xxlJobSpringExecutor.setAccessToken(accessToken);
        xxlJobSpringExecutor.setLogPath(logPath);
        xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
        return xxlJobSpringExecutor;
    }
}

步骤4:编写任务

任务类必须实现IJobHandler接口,它的execute方法即为执行器执行入口

/**
 * 分片任务
 */
@JobHandler(value="mySharding")
@Service
public class MySharding extends IJobHandler {
   @Autowired
   private MyBusiness myBusiness;
   @Override
   public ReturnT<String> execute(String param) throws Exception {
      ShardingUtil.ShardingVO shardingVO = ShardingUtil.getShardingVo();
      int index = shardingVO.getIndex();
      int total = shardingVO.getTotal();
      myBusiness.process(index,total,param);
      return SUCCESS;
   }
}

@JobHandler(value="mySharding")所标的名字,demoJobHandler专为调度中指代本任务

4.5调度中心新建任务

登录调度中心,点击下图所示“新建任务”按钮,新建示例任务。然后,参考下面截图中任务的参数配置,点击保存。

 

3、两种分布式任务对比:

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值