天天看點

XXL-Job 分布式任務排程(一)本地執行1.概述2. XXL-JOB部署排程中心3.xxljob入門案例4.任務詳解5. 輪詢測試6.分片廣播

1.概述

1.1 什麼是任務排程

我們可以考慮一下業務場景的解決方案:

  • 某電商系統需要在每天的上午10點,下午3點,晚上8點發放一批優惠券。
  • 某銀行系統需要在信用卡到期日的三天進行短信提醒,每天早上8點觸發定時任務 0 0 8 * * ?判斷哪些使用者信用卡三天之後到期,發送短信
  • 某财務系統需要在每天淩晨0:10結算前一天的财務資料,統計彙總。
  • 12306會根據車次的不同,設定某幾個時間點進行分批放票。

以上業務場景的解決方案就是任務排程。

任務排程是指系統為了自動完成特定任務,在約定的特定時刻去執行任務的過程。有了任務排程即可解放更多的人力,而是由系統自動去執行任務。

如何實作任務排程?

  • 多線程方式,結合sleep
  • JDK提供的API,例如:Timer、ScheduledExecutor
  • 架構,例如Quartz ,它是一個功能強大的任務排程架構,可以滿足更多更複雜的排程需求
  • spring task

入門案例

spring架構中預設就支援了一個任務排程,spring-task

(1)建立一個工程:spring-task-demo

pom檔案

<!-- 繼承Spring boot工程 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.5.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>
           

(2)引導類:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class TaskApplication {

    public static void main(String[] args) {
        SpringApplication.run(TaskApplication.class,args);
    }
}
           

(3)編寫案例

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class HelloJob {

    @Scheduled(cron = "0/5 * * * * ?")
    public void eat(){
        System.out.println("5秒中吃一次飯,我想成為一個胖子"+new Date());
    }
}
           

測試:啟動項目,每隔5秒中會執行一次eat方法

1.2 cron表達式

0/5 * * * * ?

秒 分 時 日 月 周 年(可選)

* * * * * ? *  
//2021 12 14 10:35 觸發一次
0 35 10 14 12 ?2021
//2021 12 月 14日 10點 每分鐘執行一次
0 * 10 14 12 ?2021
//2021 12 月 14日 10點 每隔10秒執行一次
0/10 * 10 14 12 ?2021
           

cron表達式是一個字元串, 用來設定定時規則, 由七部分組成, 每部分中間用空格隔開, 每部分的含義如下表所示:

組成部分 含義 取值範圍
第一部分 Seconds (秒) 0-59
第二部分 Minutes(分) 0-59
第三部分 Hours(時) 0-23
第四部分 Day-of-Month(天) 1-31
第五部分 Month(月) 0-11或JAN-DEC
第六部分 Day-of-Week(星期) 1-7(1表示星期日)或SUN-SAT
第七部分 Year(年) 可選 1970-2099

另外, cron表達式還可以包含一些特殊符号來設定更加靈活的定時規則, 如下表所示:

符号 含義
? 表示不确定的值。當兩個子表達式其中一個被指定了值以後,為了避免沖突,需要将另外一個的值設為“?”。例如:想在每月20日觸發排程,不管20号是星期幾,隻能用如下寫法:0 0 0 20 * ?,其中最後以為隻能用“?”
* 代表所有可能的值
, 設定多個值,例如”26,29,33”表示在26分,29分和33分各自運作一次任務
- 設定取值範圍,例如”5-20”,表示從5分到20分鐘每分鐘運作一次任務
/ 設定頻率或間隔,如"1/15"表示從1分開始,每隔15分鐘運作一次任務
L 日 周 用于每月,或每周,表示每月的最後一天,或每個月的最後星期幾,例如"6L"表示"每月的最後一個星期五"
W 表示離給定日期最近的工作日,例如"15W"放在每月(day-of-month)上表示"離本月15日最近的工作日"
# 表示該月第幾個周X。例如”6#3”表示該月第3個周五

為了讓大家更熟悉cron表達式的用法, 接下來我們給大家列舉了一些例子, 如下表所示:

| **cron表達式**     | **含義**                                |
| ------------------ | --------------------------------------- |
| */5 * * * * ?      | 每隔5秒運作一次任務                     |
| 0 0 23 * * ?       | 每天23點運作一次任務                    |
| 0 0 1 1 * ?        | 每月1号淩晨1點運作一次任務              |
| 0 0 23 L * ?       | 每月最後一天23點運作一次任務            |
| 0 26,29,33 * * * ? | 在26分、29分、33分運作一次任務          |
| 0 0/30 9-17 * * ?  | 朝九晚五工作時間内每半小時運作一次任務  |
| 0 15 10 ? * 6#3    | 每月的第三個星期五上午10:15運作一次任務 |
           

1.3 什麼是分布式任務排程

目前軟體的架構已經開始向分布式架構轉變,将單體結構拆分為若幹服務,服務之間通過網絡互動來完成業務處理。在分布式架構下,一個服務往往會部署多個執行個體來運作我們的業務,如果在這種分布式系統環境下運作任務排程,我們稱之為分布式任務排程。

XXL-Job 分布式任務排程(一)本地執行1.概述2. XXL-JOB部署排程中心3.xxljob入門案例4.任務詳解5. 輪詢測試6.分片廣播

将任務排程程式分布式建構,這樣就可以具有分布式系統的特點,并且提高任務的排程處理能力:

1、并行任務排程

并行任務排程實作靠多線程,如果有大量任務需要排程,此時光靠多線程就會有瓶頸了,因為一台計算機CPU的處理能力是有限的。

如果将任務排程程式分布式部署,每個結點還可以部署為叢集,這樣就可以讓多台計算機共同去完成任務排程,我們可以将任務分割為若幹個分片,由不同的執行個體并行執行,來提高任務排程的處理效率。

2、高可用

若某一個執行個體當機,不影響其他執行個體來執行任務。

3、彈性擴容

當叢集中增加執行個體就可以提高并執行任務的處理效率。

4、任務管理與監測

對系統中存在的所有定時任務進行統一的管理及監測。讓開發人員及運維人員能夠時刻了解任務執行情況,進而做出快速的應急處理響應。

分布式任務排程面臨的問題:

當任務排程以叢集方式部署,同一個任務排程可能會執行多次,例如:電商系統定期發放優惠券,就可能重複發放優惠券,對公司造成損失,信用卡還款提醒就會重複執行多次,給使用者造成煩惱,是以我們需要控制相同的任務在多個運作執行個體上隻執行一次。常見解決方案:

  • 分布式鎖,多個執行個體在任務執行前首先需要擷取鎖,如果擷取失敗那麼就證明有其他服務已經在運作,如果擷取成功那麼證明沒有服務在運作定時任務,那麼就可以執行。
  • ZooKeeper選舉,利用ZooKeeper對Leader執行個體執行定時任務,執行定時任務的時候判斷自己是否是Leader,如果不是則不執行,如果是則執行業務邏輯,這樣也能達到目的。

1.4 xxl-Job簡介

針對分布式任務排程的需求,市場上出現了很多的産品:

1) TBSchedule:淘寶推出的一款非常優秀的高性能分布式排程架構,目前被應用于阿裡、京東、支付寶、國美等很多網際網路企業的流程排程系統中。但是已經多年未更新,文檔缺失嚴重,缺少維護。

2) XXL-Job:大衆點評的分布式任務排程平台,是一個輕量級分布式任務排程平台, 其核心設計目标是開發迅速、學習簡單、輕量級、易擴充。現已開放源代碼并接入多家公司線上産品線,開箱即用。

3)Elastic-job:當當網借鑒TBSchedule并基于quartz 二次開發的彈性分布式任務排程系統,功能豐富強大,采用zookeeper實作分布式協調,具有任務高可用以及分片功能。

4)Saturn: 唯品會開源的一個分布式任務排程平台,基于Elastic-job,可以全域統一配置,統一監

控,具有任務高可用以及分片功能。

XXL-JOB是一個分布式任務排程平台,其核心設計目标是開發迅速、學習簡單、輕量級、易擴充。現已開放源代碼并接入多家公司線上産品線,開箱即用。

源碼位址:https://gitee.com/xuxueli0323/xxl-job

文檔位址:https://www.xuxueli.com/xxl-job/

特性

  • 簡單靈活

    提供Web頁面對任務進行管理,管理系統支援使用者管理、權限控制;

    支援容器部署;

    支援通過通用HTTP提供跨平台任務排程;

  • 豐富的任務管理功能

    支援頁面對任務CRUD操作;

    支援在頁面編寫腳本任務、指令行任務、Java代碼任務并執行;

    支援任務級聯編排,父任務執行結束後觸發子任務執行;

    支援設定指定任務執行節點路由政策,包括輪詢、随機、廣播、故障轉移、忙碌轉移等;

    支援Cron方式、任務依賴、排程中心API接口方式觸發任務執行

  • 高性能

    任務排程流程全異步化設計實作,如異步排程、異步運作、異步回調等,有效對密集排程進行流量削峰;

  • 高可用

    任務排程中心、任務執行節點均 叢集部署,支援動态擴充、故障轉移

    支援任務配置路由故障轉移政策,執行器節點不可用是自動轉移到其他節點執行

    支援任務逾時控制、失敗重試配置

    支援任務處理阻塞政策:排程當任務執行節點忙碌時來不及執行任務的處理政策,包括:串行、抛棄、覆寫政策

  • 易于監控運維

    支援設定任務失敗郵件告警,預留接口支援短信、釘釘告警;

    支援實時檢視任務執行運作資料統計圖表、任務進度監控資料、任務完整執行日志;

2. XXL-JOB部署排程中心

2.1. XXL-Job

在分布式架構下,通過XXL-Job實作定時任務

XXL-Job 分布式任務排程(一)本地執行1.概述2. XXL-JOB部署排程中心3.xxljob入門案例4.任務詳解5. 輪詢測試6.分片廣播

排程中心:負責管理排程資訊,按照排程配置發出排程請求,自身不承擔業務代碼。

任務執行器:負責接收排程請求并執行任務邏輯。

任務:專注于任務的處理。

排程中心會發出排程請求,任務執行器接收到請求之後會去執行任務,任務則專注于任務業務的處理。

2.2 環境搭建

  1. 導入資料庫腳本
  2. 修改application.properties檔案中的資料源資訊
    XXL-Job 分布式任務排程(一)本地執行1.概述2. XXL-JOB部署排程中心3.xxljob入門案例4.任務詳解5. 輪詢測試6.分片廣播
    修改為自己的資料庫位址、資料庫名 及 賬号和密碼
  3. 在xxl-job可執行檔案目錄下打開cmd,執行 指令:
java -jar xxl-job-admin-2.3.0.jar
           
  1. 登入http://localhost:10086/xxl-job-admin/
  2. 賬号密碼為 admin 123456
XXL-Job 分布式任務排程(一)本地執行1.概述2. XXL-JOB部署排程中心3.xxljob入門案例4.任務詳解5. 輪詢測試6.分片廣播

3.xxljob入門案例

3.1 入門案例編寫

3.1.1 配置執行器

任務排程中心,點選進入"執行器管理"界面, 如下圖:

XXL-Job 分布式任務排程(一)本地執行1.概述2. XXL-JOB部署排程中心3.xxljob入門案例4.任務詳解5. 輪詢測試6.分片廣播

1、此處的AppName,會在建立任務時被選擇,每個任務必然要選擇一個執行器。

2、“執行器清單” 中顯示線上的執行器清單, 支援編輯删除。

以下是執行器的屬性說明:

屬性名稱 說明
AppName 是每個執行器叢集的唯一标示AppName, 執行器會周期性以AppName為對象進行自動注冊。可通過該配置自動發現注冊成功的執行器, 供任務排程時使用;
名稱 執行器的名稱, 因為AppName限制字母數字等組成,可讀性不強, 名稱為了提高執行器的可讀性;
排序 執行器的排序, 系統中需要執行器的地方,如任務新增, 将會按照該排序讀取可用的執行器清單;
注冊方式 排程中心擷取執行器位址的方式;
機器位址 注冊方式為"手動錄入"時有效,支援人工維護執行器的位址資訊;

具體操作:

(1)新增執行器:

XXL-Job 分布式任務排程(一)本地執行1.概述2. XXL-JOB部署排程中心3.xxljob入門案例4.任務詳解5. 輪詢測試6.分片廣播

(2)自動注冊和手動注冊的差別和配置

XXL-Job 分布式任務排程(一)本地執行1.概述2. XXL-JOB部署排程中心3.xxljob入門案例4.任務詳解5. 輪詢測試6.分片廣播

3.1.2 在排程中心建立任務

在任務管理->建立,填寫以下内容

XXL-Job 分布式任務排程(一)本地執行1.概述2. XXL-JOB部署排程中心3.xxljob入門案例4.任務詳解5. 輪詢測試6.分片廣播

4.任務詳解

  • 執行器:任務的綁定的執行器,任務觸發排程時将會自動發現注冊成功的執行器, 實作任務自動發現功能; 另一方面也可以友善的進行任務分組。每個任務必須綁定一個執行器, 可在 “執行器管理” 進行設定
  • 任務描述:任務的描述資訊,便于任務管理

    路由政策:當執行器叢集部署時,提供豐富的路由政策,包括

    • FIRST(第一個):固定選擇第一個機器;
    • LAST(最後一個):固定選擇最後一個機器;
    • ROUND(輪詢):
    • RANDOM(随機):随機選擇線上的機器;
    • CONSISTENT_HASH(一緻性HASH):每個任務按照Hash算法固定選擇某一台機器,且所有任務均勻散列在不同機器上。
    • LEAST_FREQUENTLY_USED(最不經常使用):使用頻率最低的機器優先被選舉;
    • LEAST_RECENTLY_USED(最近最久未使用):最久為使用的機器優先被選舉;
    • FAILOVER(故障轉移):按照順序依次進行心跳檢測,第一個心跳檢測成功的機器標明為目标執行器并發起排程;
    • BUSYOVER(忙碌轉移):按照順序依次進行空閑檢測,第一個空閑檢測成功的機器標明為目标執行器并發起排程;
    • SHARDING_BROADCAST(分片廣播):廣播觸發對應叢集中所有機器執行一次任務,同時系統自動傳遞分片參數;可根據分片參數開發分片任務;
  • Cron:觸發任務執行的Cron表達式
  • 運作模式:
    • BEAN模式:任務以JobHandler方式維護在執行器端;需要結合 “JobHandler” 屬性比對執行器中任務;
    • GLUE模式(Java):任務以源碼方式維護在排程中心;該模式的任務實際上是一段繼承自IJobHandler的Java類代碼并 “groovy” 源碼方式維護,它在執行器項目中運作,可使用@Resource/@Autowire注入執行器裡中的其他服務;
    • GLUE模式(Shell):任務以源碼方式維護在排程中心;該模式的任務實際上是一段 “shell” 腳本;
    • GLUE模式(Python):任務以源碼方式維護在排程中心;該模式的任務實際上是一段 “python” 腳本;
    • GLUE模式(PHP):任務以源碼方式維護在排程中心;該模式的任務實際上是一段 “php” 腳本;
    • GLUE模式(NodeJS):任務以源碼方式維護在排程中心;該模式的任務實際上是一段 “nodejs” 腳本;
    • GLUE模式(PowerShell):任務以源碼方式維護在排程中心;該模式的任務實際上是一段 “PowerShell” 腳本;
  • JobHandler:運作模式為 “BEAN模式” 時生效,對應執行器中新開發的JobHandler類“@JobHandler”注解自定義的value值;
  • 阻塞處理政策:排程過于密集執行器來不及處理時的處理政策;
    • 單機串行(預設):排程請求進入單機執行器後,排程請求進入FIFO隊列并以串行方式運作;
    • 丢棄後續排程:排程請求進入單機執行器後,發現執行器存在運作的排程任務,本次請求将會被丢棄并标記為失敗;
    • 覆寫之前排程:排程請求進入單機執行器後,發現執行器存在運作的排程任務,将會終止運作中的排程任務并清空隊列,然後運作本地排程任務;
  • 子任務:每個任務都擁有一個唯一的任務ID(任務ID可以從任務清單擷取),當本任務執行結束并且執行成功時,将會觸發子任務ID所對應的任務的一次主動排程。
  • 任務逾時時間:支援自定義任務逾時時間,任務運作逾時将會主動中斷任務;
  • 失敗重試次數;支援自定義任務失敗重試次數,當任務失敗時将會按照預設的失敗重試次數主動進行重試;
  • 報警郵件:任務排程失敗時郵件通知的郵箱位址,支援配置多郵箱位址,配置多個郵箱位址時用逗号分隔;
  • 負責人:任務的負責人;
  • 執行參數:任務執行所需的參數;

4.1 搭建springboot項目

建立項目:xxl-job-demo

(1)pom檔案

<groupId>com.itheima</groupId>
<artifactId>xxl-job-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 繼承Spring boot工程 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.5.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- xxl-job -->
    <dependency>
        <groupId>com.xuxueli</groupId>
        <artifactId>xxl-job-core</artifactId>
        <version>2.2.0-SNAPSHOT</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
           

注意:如果項目中沒有找到

xxl-job-core

這個依賴,需要把這個依賴安裝到本地的maven倉庫

XXL-Job 分布式任務排程(一)本地執行1.概述2. XXL-JOB部署排程中心3.xxljob入門案例4.任務詳解5. 輪詢測試6.分片廣播

(2)配置有兩個,一個是application.properties,另外一個是日志配置:logback.xml

application.properties

server:
  port: 8881
xxl:
  job:
    admin:
      addresses: http://192.168.200.130:8888/xxl-job-admin
    executor:
      appname: xxl-job-sharding-sample
      port: 9999
           

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="1 seconds">

    <contextName>logback</contextName>
    <property name="log.path" value="/data/applogs/xxl-job/xxl-job-executor-sample-springboot.log"/>

    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}.%d{yyyy-MM-dd}.zip</fileNamePattern>
        </rollingPolicy>
        <encoder>
            <pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
            </pattern>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="console"/>
        <appender-ref ref="file"/>
    </root>

</configuration>
           

(3)引導類:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class XxlJobApplication {

    public static void main(String[] args) {
        SpringApplication.run(XxlJobApplication.class,args);
    }
}
           

4.2 添加xxl-job配置

添加配置類:

這個類主要是建立了任務執行器,參考官方案例編寫,無須改動

import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * xxl-job config
 *
 * @author xuxueli 2017-04-28
 */
@Configuration
public class XxlJobConfig {
    private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);

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

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

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

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

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

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

    @Value("${xxl.job.executor.logpath}")
    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);
        xxlJobSpringExecutor.setAppName(appName);
        xxlJobSpringExecutor.setAddress(address);
        xxlJobSpringExecutor.setIp(ip);
        xxlJobSpringExecutor.setPort(port);
        xxlJobSpringExecutor.setAccessToken(accessToken);
        xxlJobSpringExecutor.setLogPath(logPath);
        xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);

        return xxlJobSpringExecutor;
    }

    /**
     * 針對多網卡、容器内部署等情況,可借助 "spring-cloud-commons" 提供的 "InetUtils" 元件靈活定制注冊IP;
     *
     *      1、引入依賴:
     *          <dependency>
     *             <groupId>org.springframework.cloud</groupId>
     *             <artifactId>spring-cloud-commons</artifactId>
     *             <version>${version}</version>
     *         </dependency>
     *
     *      2、配置檔案,或者容器啟動變量
     *          spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
     *
     *      3、擷取IP
     *          String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
     */


}
           

4.3 建立任務

import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;


@Component
public class HelloJob {

    @Value("${server.port}")
    private String appPort;

    @XxlJob("helloJob")
    public ReturnT<String> hello(String param) throws Exception {
        System.out.println("helloJob:"+ LocalDateTime.now()+",端口号"+appPort);
        return ReturnT.SUCCESS;
    }
}

           

@XxlJob("helloJob")

這個一定要與排程中心建立任務的JobHandler的值保持一緻,如下圖:

XXL-Job 分布式任務排程(一)本地執行1.概述2. XXL-JOB部署排程中心3.xxljob入門案例4.任務詳解5. 輪詢測試6.分片廣播

5. 輪詢測試

(1)首先啟動排程中心

(2)啟動xxl-job-demo項目,為了展示更好的效果,可以同時啟動三個項目,用同一個JobHandler,檢視處理方式。

在啟動多個項目的時候,端口需要切換,連接配接xxl-job的執行器端口不同相同

服務一:預設啟動8801端口,執行器端口為9999

idea中不用其他配置,直接啟動項目即可

服務二:項目端口:8802,執行器端口:9998

idea配置如下:

  • 編輯配置,Edit Configurations…
    XXL-Job 分布式任務排程(一)本地執行1.概述2. XXL-JOB部署排程中心3.xxljob入門案例4.任務詳解5. 輪詢測試6.分片廣播
  • 選中XxlJobApplication,點選複制
    XXL-Job 分布式任務排程(一)本地執行1.概述2. XXL-JOB部署排程中心3.xxljob入門案例4.任務詳解5. 輪詢測試6.分片廣播
    啟動:選中8802啟動項目
    XXL-Job 分布式任務排程(一)本地執行1.概述2. XXL-JOB部署排程中心3.xxljob入門案例4.任務詳解5. 輪詢測試6.分片廣播
    服務三:項目端口:8803,執行器端口:9997
XXL-Job 分布式任務排程(一)本地執行1.概述2. XXL-JOB部署排程中心3.xxljob入門案例4.任務詳解5. 輪詢測試6.分片廣播

(3)測試效果

三個項目啟動後,可以檢視到是輪詢的方式分别去執行目前排程任務。

6.分片廣播

6.1 廣播任務和動态分片

6.1.1 什麼是作業分片

作業分片是指任務的分布式執行,需要将一個任務拆分為多個獨立的任務項,然後由分布式的應用執行個體分别執行某一個或幾個分片項。

XXL-Job 分布式任務排程(一)本地執行1.概述2. XXL-JOB部署排程中心3.xxljob入門案例4.任務詳解5. 輪詢測試6.分片廣播

6.1.2 XXL-JOB分片

  • 廣播任務:

    執行器叢集部署,任務路由政策選擇"分片廣播"情況下,一次任務排程将會廣播觸發叢集中所有執行器執行一次任務,系統會自動傳遞分片參數,可根據分片參數開發分片任務;

  • 動态分片:

    分片廣播任務以執行器為次元進行分片,支援動态擴容執行器叢集,進而動态增加分片數量,協同進行業務處理;在進行大資料量業務操作時可顯著提升任務處理能力和速度。

XXL-Job 分布式任務排程(一)本地執行1.概述2. XXL-JOB部署排程中心3.xxljob入門案例4.任務詳解5. 輪詢測試6.分片廣播

6.1.3 XXL-JOB支援分片的好處

  • 分片項與業務處了解耦

    XXL-JOB并不直接提供資料處理的功能,架構隻會将分片項配置設定至各個運作中的作業伺服器,開發者需要自行處理分片項與真實資料的對應關系。

  • 最大限度利用資源

    基于業務需求配置合理數量的執行器服務,合理設定分片,作業将會最大限度合理的利用分布式資源。

6.1.4 分片廣播案例示範

目标:實作XXL-JOB作業分片的示範

方案分析:規劃一個任務,兩個分片,對應兩個執行器,每個分片處理一部分任務。

實作步驟:

  • 建立分片執行器:
    XXL-Job 分布式任務排程(一)本地執行1.概述2. XXL-JOB部署排程中心3.xxljob入門案例4.任務詳解5. 輪詢測試6.分片廣播
  • 建立任務

    指定剛才建立的分片執行器,在路由政策這一欄選擇分片廣播

    XXL-Job 分布式任務排程(一)本地執行1.概述2. XXL-JOB部署排程中心3.xxljob入門案例4.任務詳解5. 輪詢測試6.分片廣播
  • 分片廣播代碼

    分片參數屬性說明:

    • index:目前分片序号(從0開始),執行器叢集清單中目前執行器的序号;
    • total:總分片數,執行器叢集的總機器數量;

目前有一萬條資料,使用兩個分片同時執行

/**
     * 2、分片廣播任務
     */
@XxlJob("shardingJobHandler")
public ReturnT<String> shardingJobHandler(String param) throws Exception {

    // 分片參數
    ShardingUtil.ShardingVO shardingVO = ShardingUtil.getShardingVo();
    XxlJobLogger.log("分片參數:目前分片序号 = {}, 總分片數 = {}", shardingVO.getIndex(), shardingVO.getTotal());

    List<Integer> list = getList();
    for (Integer integer : list) {
        if(integer % shardingVO.getTotal() == shardingVO.getIndex()){
            System.out.println("第"+shardingVO.getIndex()+"分片執行,執行資料為:"+integer);
        }
    }

    return ReturnT.SUCCESS;
}

public static List<Integer> getList(){
    List<Integer> list = new ArrayList<>();
    for (int i = 0; i < 10000 ; i++) {
        list.add(i);
    }
    return list;
}
           

結論:通過排程日志可以看出,同一個任務在給定的時間點、給定的時間間隔被多個程序不斷調用,實作了任務的分片,展現了分布式任務排程的并行任務排程的特點。