第四章 分佈式任務調度筆記

代碼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=[email protected]
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、兩種分佈式任務對比:

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章