XXL_JOB分佈式任務調度平臺

前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

官方地址:分佈式任務調度平臺XXL-JOB

1、下載部署

1.1、下載

https://github.com/xuxueli/xxl-job

1.2、部署

1.2.1、目錄結構:

xxl-job-admin:調度中心
xxl-job-core:公共依賴
xxl-job-executor-samples:執行器Sample示例(選擇合適的版本執行器,可直接使用,也可以參考其並將現有項目改造成執行器)
    :xxl-job-executor-sample-springboot:Springboot版本,通過Springboot管理執行器,推薦這種方式;
    :xxl-job-executor-sample-spring:Spring版本,通過Spring容器管理執行器,比較通用;
    :xxl-job-executor-sample-frameless:無框架版本;
    :xxl-job-executor-sample-jfinal:JFinal版本,通過JFinal管理執行器;
    :xxl-job-executor-sample-nutz:Nutz版本,通過Nutz管理執行器;
    :xxl-job-executor-sample-jboot:jboot版本,通過jboot管理執行器;

1.2、SpringBoot選擇

除了SpringBoot,其他的對我來說沒有用,刪掉其他的,我只保留的SpringBoot

image-20200514164259108

1.2.1、調度中心

統一管理任務調度平臺上調度任務,負責觸發調度執行,並且提供任務管理平臺。

1.2.1.1、properties

### web
server.port=8080
server.servlet.context-path=/xxl-job-admin

### actuator
management.server.servlet.context-path=/actuator
management.health.mail.enabled=false

### resources
spring.mvc.servlet.load-on-startup=0
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
#mybatis.type-aliases-package=com.xxl.job.admin.core.model

### datasource-pool
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.maximum-pool-size=30
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.pool-name=HikariCP
spring.datasource.hikari.max-lifetime=900000
spring.datasource.hikari.connection-timeout=10000
spring.datasource.hikari.connection-test-query=SELECT 1

### 調度中心JDBC鏈接:鏈接地址請保持和 2.1章節 所創建的調度數據庫的地址一致
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver



### 報警郵箱
spring.mail.host=smtp.163.com
spring.mail.port=25
[email protected]
spring.mail.password=Zhangyj..123
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory

### 調度中心通訊TOKEN [選填]:非空時啓用;
xxl.job.accessToken=

### 調度中心國際化配置 [必填]: 默認爲 "zh_CN"/中文簡體, 可選範圍爲 "zh_CN"/中文簡體, "zh_TC"/中文繁體 and "en"/英文;
xxl.job.i18n=zh_CN


## 調度線程池最大線程配置【必填】
xxl.job.triggerpool.fast.max=200
xxl.job.triggerpool.slow.max=100

### 調度中心日誌表數據保存天數 [必填]:過期日誌自動清理;限制大於等於7時生效,否則, 如-1,關閉自動清理功能;
xxl.job.logretentiondays=30

1.2.2:執行器項目

作用:負責接收“調度中心”的調度並執行;可直接部署執行器,也可以將執行器集成到現有業務項目中。

12.2.1、properties

# web port
server.port=8081
# no web
#spring.main.web-environment=false

# log config
logging.config=classpath:logback.xml


### 調度中心部署跟地址 [選填]:
# 如調度中心集羣部署存在多個地址則用逗號分隔。執行器將會使用該地址進行"執行器心跳註冊"和"任務結果回調";爲空則關閉自動註冊;
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin

### 執行器通訊TOKEN [選填]:非空時啓用;XxlJobConfig
xxl.job.accessToken=

### 執行器AppName [選填]:執行器心跳註冊分組依據;爲空則關閉自動註冊
xxl.job.executor.appname=xxl-job-executor-sample
### 執行器註冊 [選填]:優先使用該配置作爲註冊地址,爲空時使用內嵌服務 ”IP:PORT“ 作爲註冊地址。從而更靈活的支持容器類型執行器動態IP和動態映射端口問題。
xxl.job.executor.address=
### 執行器IP [選填]:默認爲空表示自動獲取IP,多網卡時可手動設置指定IP,該IP不會綁定Host僅作爲通訊實用;地址信息用於 "執行器註冊" 和 "調度中心請求並觸發任務";
xxl.job.executor.ip=
### 執行器端口號 [選填]:小於等於0則自動獲取;默認端口爲9999,單機部署多個執行器時,注意要配置不同執行器端口;
# 這裏相當的重要,和上面應用的端口不同,也就是執行器通過下面的端口進行服務
xxl.job.executor.port=9999
### 執行器運行日誌文件存儲磁盤路徑 [選填] :需要對該路徑擁有讀寫權限;爲空則使用默認路徑;
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
### 執行器日誌文件保存天數 [選填] : 過期日誌自動清理, 限制值大於等於3時生效; 否則, 如-1, 關閉自動清理功能;
xxl.job.executor.logretentiondays=30

1.3、啓動:

1.3.1、啓動調度中心:xxl-job-admin

http://127.0.0.1:8080//xxl-job-admin
“admin/123456

image-20200514165313578

2、定時器介紹

2.1、配置屬性

image-20200514175519193

2.1.1、執行器

任務的綁定的執行器,任務觸發調度時將會自動發現註冊成功的執行器, 實現任務自動發現功能; 另一方面也可以方便的進行任務分組。每個任務必須綁定一個執行器, 可在 “執行器管理” 進行設置;

image-20200514175450889

2.1.2、 任務描述

任務的描述信息,便於任務管理;

image-20200514175618084

2.1.3、路由策略

當執行器集羣部署時,提供豐富的路由策略,包括;

FIRST(第一個) 固定選擇第一個機器;
LAST(最後一個) 固定選擇最後一個機器;
ROUND(輪詢)
RANDOM(隨機) 隨機選擇在線的機器
CONSISTENT_HASH(一致性HASH) 每個任務按照Hash算法固定選擇某一臺機器,且所有任務均勻散列在不同機器上。
LEAST_FREQUENTLY_USED(最不經常使用): 使用頻率最低的機器優先被選舉;
LEAST_RECENTLY_USED(最近最久未使用) 最久未使用的機器優先被選舉
FAILOVER(故障轉移) 按照順序依次進行心跳檢測,第一個心跳檢測成功的機器選定爲目標執行器併發起調度;
BUSYOVER(忙碌轉移) 按照順序依次進行空閒檢測,第一個空閒檢測成功的機器選定爲目標執行器併發起調度;
SHARDING_BROADCAST(分片廣播) 廣播觸發對應集羣中所有機器執行一次任務,同時系統自動傳遞分片參數;可根據分片參數開發分片任務;

2.1.4、Cron

觸發任務執行的Cron表達式;

2.1.5、運行模式

BEAN模式 任務以JobHandler方式維護在執行器端;需要結合 “JobHandler” 屬性匹配執行器中任務;
GLUE模式 任務以源碼方式維護在調度中心;任務以JobHandler方式維護在執行器端;需要結合 “JobHandler” 屬性匹配執行器中任務;
GLUE模式(Java) 該模式的任務實際上是一段繼承自IJobHandler的Java類代碼並 “groovy” 源碼方式維護,它在執行器項目中運行,可使用@Resource/@Autowire注入執行器裏中的其他服務;
GLUE模式(Shell) 該模式的任務實際上是一段 “shell” 腳本;
GLUE模式(Python) 該模式的任務實際上是一段 “python” 腳本;
GLUE模式(PHP) 該模式的任務實際上是一段 “php” 腳本;
GLUE模式(NodeJS) 該模式的任務實際上是一段 “nodejs” 腳本;
GLUE模式(PowerShell) 該模式的任務實際上是一段 “PowerShell” 腳本;

2.1.6、JobHandler

運行模式爲 “BEAN模式” 時生效,對應執行器中新開發的JobHandler類“@JobHandler”註解自定義的value值;

2.1.7、阻塞處理策略

調度過於密集執行器來不及處理時的處理策略;

如果當前任務還沒執行完成,又來了任務的處理策略 。我們一定要儘可能避免此類情況

阻塞處理策略
單機串行(默認) 調度請求進入單機執行器後,調度請求進入FIFO隊列並以串行方式運行;
丟棄後續調度 調度請求進入單機執行器後,發現執行器存在運行的調度任務,本次請求將會被丟棄並標記爲失敗;
覆蓋之前調度 調度請求進入單機執行器後,發現執行器存在運行的調度任務,將會終止運行中的調度任務並清空隊列,然後運行本地調度任務;

2.1.9、子任務Id

每個任務都擁有一個唯一的任務ID(任務ID可以從任務列表獲取),當本任務執行結束並且執行成功時,將會觸發子任務ID所對應的任務的一次主動調度。

2.1.10、任務超時時間

支持自定義任務超時時間,任務運行超時將會主動中斷任務,同下面調度日誌裏面的終止任務;

2.1.11、失敗重試次數

支持自定義任務失敗重試次數,當任務失敗時將會按照預設的失敗重試次數主動進行重試;

2.1.12、負責人

任務的負責人;

2.1.13、報警郵件

任務調度失敗時郵件通知的郵箱地址,支持配置多郵箱地址,配置多個郵箱地址時用逗號分隔;

2.1.14、執行參數

任務執行所需的參數

3、BEAN模式

任務以JobHandler方式維護在執行器端;需要結合 “JobHandler” 屬性匹配執行器中任務

3.1、方法形式

3.1.1、執行器項目

package com.xxl.job.executor.service.jobhandler.bean;

import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * XxlJob開發示例(Bean模式)
 * <p>
 * 開發步驟:
 * 1、在Spring Bean實例中,開發Job方法,方式格式要求爲 "public ReturnT<String> execute(String param)"
 * 2、爲Job方法添加註解 "@XxlJob(value="自定義jobhandler名稱", init = "JobHandler初始化方法", destroy = "JobHandler銷燬方法")",註解value值對應的是調度中心新建任務的JobHandler屬性的值。
 * 3、執行日誌:需要通過 "XxlJobLogger.log" 打印執行日誌;
 */
@Component
@Slf4j
public class BeanMethodXxlJob {


    /**
     * 1、簡單任務示例(Bean模式)
     */
    @XxlJob("demoJobHandler")
    public ReturnT<String> demoJobHandler(String param) throws Exception {
        log.info("任務【demoJobHandler】開始執行, 請求參數:{}", param);

        //任務調度器日誌
        XxlJobLogger.log("XXL-JOB, 請求參數:{}", param);
        return ReturnT.SUCCESS;
    }

    /**
     * 2、生命週期任務示例:任務初始化與銷燬時,支持自定義相關邏輯;
     */
    @XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")
    public ReturnT<String> demoJobHandler2(String param) throws Exception {
        log.info("任務【demoJobHandler2】開始執行, 請求參數:{}", param);

        //任務調度器日誌
        XxlJobLogger.log("XXL-JOB, Hello World.");
        return ReturnT.SUCCESS;
    }

    public void init() {
        log.info("任務【demoJobHandler2】開始執行 init");
    }

    public void destroy() {
        log.info("任務【demoJobHandler2】開始執行 destroy");
    }


}

3.1.2、調度中心頁面操作

3.1.2.1、demoJobHandler

0 */1 * * * ?  每分鐘執行一次

image-20200514171037105

image-20200514171544980

3.1.2.2、demoJobHandler2

image-20200514171746883

image-20200514171759076

4、GLUE(java)模式

任務以源碼方式維護在調度中心;該模式的任務實際上是一段繼承自IJobHandler的Java類代碼並 “groovy” 源碼方式維護,它在執行器項目中運行,可使用@Resource/@Autowire注入執行器裏中的其他服務;

4.1、GLUE模式(Java)

4.1.1、glueJobHandle

4.1.1.1、創建

image-20200514173917522

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-jp2MWFgF-1591086758306)(https://raw.githubusercontent.com/HealerJean/HealerJean.github.io/master/blogImages/image-20200514173938394.png)]

package com.xxl.job.service.handler;

import com.xxl.job.core.log.XxlJobLogger;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;

public class DemoGlueJobHandler extends IJobHandler {

    @Override
    public ReturnT<String> execute(String param) throws Exception {
        XxlJobLogger.log("GlueJob 請求參數:{}", param);
        return ReturnT.SUCCESS;
    }
}

image-20200514174042724

4.1.1.2、查看日誌

image-20200514174259824

image-20200514174320434

                
2020-05-14 17:41:57 [com.xxl.job.core.thread.JobThread#run]-[124]-[Thread-19] 
----------- xxl-job job execute start -----------
----------- Param:HealerJean
2020-05-14 17:41:57 [com.xxl.job.core.handler.impl.GlueJobHandler#execute]-[26]-[Thread-19] ----------- glue.version:1589449244000 -----------
2020-05-14 17:41:57 [sun.reflect.NativeMethodAccessorImpl#invoke0]-[-2]-[Thread-19] GlueJob 請求參數:HealerJean
2020-05-14 17:41:57 [com.xxl.job.core.thread.JobThread#run]-[164]-[Thread-19] 
----------- xxl-job job execute end(finish) -----------
----------- ReturnT:ReturnT [code=200, msg=null, content=null]
2020-05-14 17:41:57 [com.xxl.job.core.thread.TriggerCallbackThread#callbackLog]-[191]-[xxl-job, executor TriggerCallbackThread] 
----------- xxl-job job callback finish.

[Load Log Finish]

5、操作指南

5.1、執行器管理

AppName: 是每個執行器集羣的唯一標示AppName, 執行器會週期性以AppName爲對象進行自動註冊。可通過該配置自動發現註冊成功的執行器, 供任務調度時使用;

名稱:執行器的名稱, 因爲AppName限制字母數字等組成,可讀性不強, 名稱爲了提高執行器的可讀性;

排序:執行器的排序, 系統中需要執行器的地方,如任務新增, 將會按照該排序讀取可用的執行器列表;

註冊方式:調度中心獲取執行器地址的方式

1、自動註冊:執行器自動進行執行器註冊,調度中心通過底層註冊表可以動態發現執行器機器地址

2、手動錄入:人工手動錄入執行器的地址信息,多地址逗號分隔,供調度中心使用;

機器地址:"註冊方式"爲"手動錄入"時有效,支持人工維護執行器的地址信息;`

image-20200514184425782

5.2、調度日誌

image-20200514184833583

調度時間:"調度中心"觸發本次調度並向"執行器"發送任務執行信號的時間;

調度結果:"調度中心"觸發本次調度的結果,200表示成功,500或其他表示失敗;

調度備註:"調度中心"觸發本次調度的日誌信息;

任務觸發類型:失敗重試觸發
調度機器:10.236.150.223
執行器-註冊方式:自動註冊
執行器-地址列表:[http://10.236.150.223:9999/]
路由策略:第一個
阻塞處理策略:單機串行
任務超時時間:0
失敗重試次數:3

>>>>>>>>>>>觸發調度<<<<<<<<<<<
觸發調度:
address:http://10.236.150.223:9999/
code:200
msg:null

執行時間:"執行器"中本次任務執行結束後回調的時間;

執行結果:"執行器"中本次任務執行的結果,200表示成功,500或其他表示失敗;

執行備註:"執行器"中本次任務執行的日誌信息

操作:

1、"執行日誌"按鈕:點擊可查看本地任務執行的詳細日誌信息;詳見“4.8 查看執行日誌”;

image-20200514185319106

2、"終止任務"按鈕:僅針對執行中的任務。在任務日誌界面,點擊右側的“終止任務”按鈕,將會向本次任務對應的執行器發送任務終止請求,將會終止掉本次任務,同時會清空掉整個任務執行隊列。

任務終止時通過 “interrupt” 執行線程的方式實現, 將會觸發 “InterruptedException” 異常。因此如果JobHandler內部catch到了該異常並消化掉的話, 任務終止功能將不可用。

因此, 如果遇到上述任務終止不可用的情況, 需要在JobHandler中應該針對 “InterruptedException” 異常進行特殊處理 (向上拋出) , 正確邏輯如下:

try{
    // do something
} catch (Exception e) {
    if (e instanceof InterruptedException) {
        throw e;
    }
    logger.warn("{}", e);
}

而且,在JobHandler中開啓子線程時,子線程也不可catch處理”InterruptedException”,應該主動向上拋出。

任務終止時會執行對應JobHandler的”destroy()”方法,可以藉助該方法處理一些資源回收的邏輯。

5.3、用戶管理

管理員:擁有全量權限,支持在線管理用戶信息,爲用戶分配權限,權限分配粒度爲執行器;

普通用戶:僅擁有被分配權限的執行器,及相關任務的操作權限;

image-20200514185612864

6、總體設計

6.1、源碼目錄介紹

- /doc :文檔資料
- /db :“調度數據庫”建表腳本
- /xxl-job-admin :調度中心,項目源碼
- /xxl-job-core :公共Jar依賴
- /xxl-job-executor-samples :執行器,Sample示例項目(大家可以在該項目上進行開發,也可以將現有項目改造生成執行器項目)

6.2、調度數據庫

- xxl_job_lock:任務調度鎖表;
- xxl_job_group:執行器信息表,維護任務執行器信息;
- xxl_job_info:調度擴展信息表: 用於保存XXL-JOB調度任務的擴展信息,如任務分組、任務名、機器地址、執行器、執行入參和報警郵件等等;
- xxl_job_log:調度日誌表: 用於保存XXL-JOB任務調度的歷史信息,如調度結果、執行結果、調度入參、調度機器和執行器等等;
- xxl_job_log_report:調度日誌報表:用戶存儲XXL-JOB任務調度日誌的報表,調度中心報表功能頁面會用到;
- xxl_job_logglue:任務GLUE日誌:用於保存GLUE更新歷史,用於支持GLUE的版本回溯功能;
- xxl_job_registry:執行器註冊表,維護在線的執行器和調度中心機器地址信息;
- xxl_job_user:系統用戶表;

7、quartz的不足

問題一:調用API的的方式操作任務,不人性化;

問題二:需要持久化業務QuartzJobBean到底層數據表中,系統侵入性相當嚴重。

問題三:調度邏輯和QuartzJobBean耦合在同一個項目中,這將導致一個問題,在調度任務數量逐漸增多,同時調度任務邏輯逐漸加重的情況下,此時調度系統的性能將大大受限於業務;

問題四:quartz底層以“搶佔式”獲取DB鎖並由搶佔成功節點負責運行任務,會導致節點負載懸殊非常大;而XXL-JOB通過執行器實現“協同分配式”運行任務(其實也是樂觀鎖獲取任務),充分發揮集羣優勢,負載各節點均衡。

主要還是入侵比較嚴重吧。而且分佈式用XXLJob,更好,可以給多個分佈式系統節點提供服務

ContactAuthor

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