精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

XXL-JOB真的要涼了?出現了一個王炸級別的分布式任務調度與計算框架?

開發 前端
執行到該節點時,如果該節點處于啟用狀態,那么將啟動該節點所引用工作流的一個新實例,待該實例執行完成后再同步更新該節點的狀態。

關于PowerJob

PowerJob(原OhMyScheduler)是全新一代分布式任務調度與計算框架,其主要功能特性如下:

  • 使用簡單:提供前端Web界面,允許開發者可視化地完成調度任務的管理(增、刪、改、查)、任務運行狀態監控和運行日志查看等功能。
  • 定時策略完善:支持 CRON 表達式、固定頻率、固定延遲和API四種定時調度策略。
  • 執行模式豐富:支持單機、廣播、Map、MapReduce 四種執行模式,其中 Map/MapReduce 處理器能使開發者寥寥數行代碼便獲得集群分布式計算的能力。
  • 工作流支持:支持在線配置任務依賴關系(DAG),以可視化的方式對任務進行編排,同時還支持上下游任務間的數據傳遞,以及多種節點類型(判斷節點 & 嵌套工作流節點)。
  • 執行器支持廣泛:支持 Spring Bean、內置/外置 Java 類,另外可以通過引入官方提供的依賴包,一鍵集成 Shell、Python、HTTP、SQL 等處理器,應用范圍廣。
  • 運維便捷:支持在線日志功能,執行器產生的日志可以在前端控制臺頁面實時顯示,降低 debug 成本,極大地提高開發效率。
  • 依賴精簡:最小僅依賴關系型數據庫(MySQL/PostgreSQL/Oracle/MS SQLServer...)
  • 高可用 & 高性能:調度服務器經過精心設計,一改其他調度框架基于數據庫鎖的策略,實現了無鎖化調度。部署多個調度服務器可以同時實現高可用和性能的提升(支持無限的水平擴展)。
  • 故障轉移與恢復:任務執行失敗后,可根據配置的重試策略完成重試,只要執行器集群有足夠的計算節點,任務就能順利完成。

適用場景

  • 有定時執行需求的業務場景:如每天凌晨全量同步數據、生成業務報表、未支付訂單超時取消等。
  • 有需要全部機器一同執行的業務場景:如使用廣播執行模式清理集群日志。
  • 有需要分布式處理的業務場景:比如需要更新一大批數據,單機執行耗時非常長,可以使用Map/MapReduce 處理器完成任務的分發,調動整個集群加速計算。
  • 有需要延遲執行某些任務的業務場景:比如訂單過期處理等。

同類產品對比

圖片

基本概念

分組概念

  • appName:應用名稱,建議與用戶實際接入 PowerJob 的應用名稱保持一致,用于業務分組與隔離。一個 appName 等于一個業務集群,也就是實際的一個 Java 項目。

核心概念

  • 任務(Job):描述了需要被 PowerJob 調度的任務信息,包括任務名稱、調度時間、處理器信息等。
  • 任務實例( JobInstance,簡稱 Instance):任務(Job)被調度執行后會生成任務實例(Instance),任務實例記錄了任務的運行時信息(任務與任務實例的關系類似于類與對象的關系)。
  • 作業(Task):任務實例的執行單元,一個 JobInstance 存在至少一個 Task,具體規則如下:
  1. 單機任務(STANDALONE):一個 JobInstance 對應一個 Task
  2. 廣播任務(BROADCAST):一個 JobInstance 對應 N 個 Task,N為集群機器數量,即每一臺機器都會生成一個 Task
  3. Map/MapReduce任務:一個 JobInstance 對應若干個 Task,由開發者手動 map 產生
  • 工作流(Workflow):由 DAG(有向無環圖)描述的一組任務(Job),用于任務編排。
  • 工作流實例(WorkflowInstance):工作流被調度執行后會生成工作流實例,記錄了工作流的運行時信息。

擴展概念

  • JVM 容器:以 Maven 工程項目的維度組織一堆 Java 文件(開發者開發的眾多 Java 處理器),可以通過前端網頁動態發布并被執行器加載,具有極強的擴展能力和靈活性。
  • OpenAPI:允許開發者通過接口來完成手工的操作,讓系統整體變得更加靈活。開發者可以基于 API 便捷地擴展 PowerJob 原有的功能。

定時任務類型

  • API:該任務只會由 powerjob-client 中提供的 OpenAPI 接口觸發,server 不會主動調度。
  • CRON:該任務的調度時間由 CRON 表達式指定。
  • 固定頻率:秒級任務,每隔多少毫秒運行一次,功能與 java.util.concurrent.ScheduledExecutorService#scheduleAtFixedRate 相同。
  • 固定延遲:秒級任務,延遲多少毫秒運行一次,功能與 java.util.concurrent.ScheduledExecutorService#scheduleWithFixedDelay 相同。
  • 工作流:該任務只會由其所屬的工作流調度執行,server 不會主動調度該任務。如果該任務不屬于任何一個工作流,該任務就不會被調度。

備注:固定延遲和固定頻率任務統稱秒級任務,這兩種任務無法被停止,只有任務被關閉或刪除時才能真正停止任務。

搭建PowerJob環境

本地啟動

初始化項目

git clone https://github.com/PowerJob/PowerJob.git

導入 IDE,源碼結構如下,我們需要啟動調度服務器(powerjob-server),同時在 samples 工程中編寫自己的處理器代碼

圖片

啟動調度服務器

  1. 創建數據庫(僅需要創建數據庫):找到你的 DB,運行 SQL CREATE DATABASE IF NOT EXISTS `powerjob-daily` DEFAULT CHARSET utf8mb4,搞定~
  2. 修改配置文件:配置文件的說明官方文檔寫的非常詳細,此處不再贅述。需要修改的地方為數據庫配置spring.datasource.core.jdbc-url、spring.datasource.core.username和spring.datasource.core.password,當然,有 mongoDB 的同學也可以修改spring.data.mongodb.uri以獲取完全版體驗。

powerjob-server 日常環境配置文件:application-daily.properties

oms.env=DAILY
logging.cnotallow=classpath:logback-dev.xml


####### 外部數據庫配置(需要用戶更改為自己的數據庫配置) #######
spring.datasource.core.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.core.jdbc-url=jdbc:mysql://localhost:3306/powerjob-daily?useUnicode=true&characterEncoding=UTF-8&serverTimeznotallow=Asia/Shanghai
spring.datasource.core.username=root
spring.datasource.core.password=No1Bug2Please3!
spring.datasource.core.hikari.maximum-pool-size=20
spring.datasource.core.hikari.minimum-idle=5


####### mongoDB配置,非核心依賴,通過配置 oms.mongodb.enable=false 來關閉 #######
oms.mongodb.enable=true
spring.data.mongodb.uri=mongodb://localhost:27017/powerjob-daily


####### 郵件配置(不需要郵件報警可以刪除以下配置來避免報錯) #######
spring.mail.host=smtp.163.com
spring.mail.username=zqq@163.com
spring.mail.password=GOFZPNARMVKCGONV
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true


####### 資源清理配置 #######
oms.instanceinfo.retentinotallow=1
oms.container.retention.local=1
oms.container.retention.remote=-1


####### 緩存配置 #######
oms.instance.metadata.cache.size=1024
  1. 啟動應用:完成配置文件的修改后,可以直接通過啟動類 tech.powerjob.server.PowerJobServerApplication 啟動調度服務器(注意:需要使用 daily 配置文件啟動,可自行百度搜索“SpringBoot 指定配置文件啟動”),觀察啟動日志,查看是否啟動成功~啟動成功后,訪問 http://127.0.0.1:7700/ ,如果能順利出現 Web 界面,則說明調度服務器啟動成功!
  2. 注冊應用:點擊主頁應用注冊按鈕,填入 powerjob-agent-test 和控制臺密碼(用于進入控制臺),注冊示例應用(當然你也可以注冊其他的 appName,只是別忘記在示例程序中同步修改~)

圖片圖片

docker-compose啟動

環境要求

本地需要安裝docker和docker-compose

下載代碼

git clone --depth=1 https://github.com/PowerJob/PowerJob.git

運行

cd PowerJob
docker-compose up
docker-compose up -d

剛開始啟動時,powerjob-worker-samples會啟動失敗,等powerjob-server啟動成功后,powerjob-worker-samples才會啟動成功。這大概需要幾分鐘。

運行成功后,瀏覽器訪問 http://127.0.0.1:7700/ 
應用名稱:powerjob-worker-samples
密碼:powerjob123

停止

docker-compose down
Stopping powerjob-worker-samples ... done
Stopping powerjob-server         ... done
Stopping powerjob-mysql          ... done
Removing powerjob-worker-samples ... done
Removing powerjob-server         ... done
Removing powerjob-mysql          ... done
cd PowerJob
rm -rf powerjob-data

SpringBoot集成PowerJob

添加相關maven依賴

<dependency>
  <groupId>tech.powerjob</groupId>
  <artifactId>powerjob-worker-spring-boot-starter</artifactId>
  <version>${latest.powerjob.version}</version>
</dependency>

配置文件配置

powerjob:
  worker:
    # akka 工作端口,可選,默認 27777
    akka-port: 27777
    # 接入應用名稱,用于分組隔離,推薦填寫 本 Java 項目名稱
    app-name: ${spring.application.name}
    # 調度服務器地址,IP:Port 或 域名,多值逗號分隔
    server-address: 81.70.117.188:7700
    # 持久化方式,可選,默認 disk
    store-strategy: disk
    # 任務返回結果信息的最大長度,超過這個長度的信息會被截斷,默認值 8192
    max-result-length: 8192
    # 單個任務追加的工作流上下文最大長度,超過這個長度的會被直接丟棄,默認值 8192
    max-appended-wf-context-length: 8192

處理器(Processor)開發

處理器概述

基本概念

PowerJob 支持 Python、Shell、HTTP、SQL 等眾多通用任務的處理,開發者只需要引入依賴,在控制臺配置好相關參數即可,關于這部分詳見 官方處理器 ,此處不再贅述。本章將重點闡述 Java 處理器開發方法與使用技巧。

  • Java 處理器可根據代碼所處位置劃分為內置 Java 處理器和外置 Java 處理器,前者直接集成在宿主應用(也就是接入本系統的業務應用)中,一般用來處理業務需求;后者可以在一個獨立的輕量級的 Java 工程中開發,通過 JVM 容器技術(詳見容器章節)被 worker 集群熱加載,提供 Java 的“腳本能力”,一般用于處理靈活多變的需求。
  • Java 處理器可根據對象創建者劃分為 SpringBean 處理器和普通 Java 對象處理器,前者由 Spring IOC 容器完成處理器的創建和初始化,后者則由 PowerJob 維護其生命周期。如果宿主應用支持 Spring,強烈建議使用 SpringBean 處理器,開發者僅需要將 Processor 注冊進 Spring IOC 容器(一個 @Component 注解或一句 bean 配置)即可享受 Spring 帶來的便捷之處。
  • Java處理器可根據功能劃分為單機處理器、廣播處理器、Map 處理器和 MapReduce 處理器。

單機處理器(BasicProcessor)對應了單機任務,即某個任務的某次運行只會有某一臺機器的某一個線程參與運算。

廣播處理器(BroadcastProcessor)對應了廣播任務,即某個任務的某次運行會調動集群內所有機器參與運算。

Map處理器(MapProcessor)對應了Map任務,即某個任務在運行過程中,允許產生子任務并分發到其他機器進行運算。

MapReduce 處理器(MapReduceProcessor)對應了 MapReduce 任務,在 Map 任務的基礎上,增加了所有任務結束后的匯總統計。

入參 TaskContext

TaskContext 包含了本次任務的上下文信息,具體信息如下

屬性列表(紅色標注的為常用屬性)

屬性名稱

意義/用法

jobId

任務 ID,開發者一般無需關心此參數

instanceId

任務實例 ID,全局唯一,開發者一般無需關心此參數

subInstanceId

子任務實例 ID,秒級任務使用,開發者一般無需關心此參數

taskId

采用鏈式命名法的 ID,在某個任務實例內唯一,開發者一般無需關心此參數

taskName

task 名稱,Map/MapReduce 任務的子任務的值為開發者指定,否則為系統默認值,開發者一般無需關心此參數

jobParams

任務參數

對于非工作流中的任務其值等同于控制臺錄入的任務參數;如果該任務為工作流中的任務且有配置節點參數信息,那么接收到的是節點配置的參數信息

instanceParams

任務實例參數

對于非工作流中的任務 其值 等同于 OpenAPI 傳遞的實例參數,非 OpenAPI 觸發的任務則一定為空。如果該任務為工作流中的任務那么這里實際接收到的是工作流上下文信息,建議使用 getWorkflowContext 方法獲取上下文信息 


maxRetryTimes

Task 的最大重試次數

currentRetryTimes

Task 的當前重試次數,和 maxRetryTimes 聯合起來可以判斷當前是否為該 Task 的最后一次運行機會

subTask

子 Task,Map/MapReduce 處理器專屬,開發者調用map方法時傳遞的子任務列表中的某一個

omsLogger

在線日志,用法同 Slf4J,記錄的日志可以直接通過控制臺查看,非常便捷和強大!不過使用過程中需要注意頻率,濫用在線日志會對 Server 造成巨大的壓力

userContext

用戶在 PowerJobWorkerConfig 中設置的自定義上下文

workflowContext

工作流上下文,更多信息見下方說明

工作流上下文( WorkflowContext )

該屬性是 v4.0.0 版本的重大變更之一,移除了原來的參數傳遞機制,提供了 API 讓開發者可以更加靈活便捷地在工作流中實現信息的傳遞。

屬性列表

屬性名稱

意義/用法

wfInstanceId

工作流實例 ID

data

工作流上下文數據,鍵值對

appendedContextData

當前任務向工作流上下文中追加的數據。在任務執行完成后 ProcessorTracker 會將其上報給 TaskTracker,TaskTracker 在當前任務執行完成后會將這個信息上報給 server ,追加到當前的工作流上下文中,供下游任務消費

上游任務通過  WorkflowContext#appendData2WfContext(String key,Object value)  方法向工作流上下文中追加數據,下游任務便可以通過 WorkflowContext#fetchWorkflowContext()  方法獲取到相應的數據進行消費。注意,當追加的上下文信息的 key 已經存在于當前的上下文中時,新的 value 會覆蓋之前的值。另外,每次任務實例追加的上下文數據大小也會受到 worker 的配置項  powerjob.worker.max-appended-wf-context-length 的限制,超過這個長度的會被直接丟棄。

返回值 ProcessResult

方法的返回值為 ProcessResult,代表了本次 Task 執行的結果,包含 success 和 msg 兩個屬性,分別用于傳遞 Task 是否執行成功和 Task 需要返回的信息。

處理器開發示例

單機處理器:BasicProcessor

單機執行的策略下,server 會在所有可用 worker 中選取健康度最佳的機器進行執行。單機執行任務需要實現接口 BasicProcessor,代碼示例如下:

/**
 * @Author iron.guo
 * @Date 2023/1/7
 * @Description
 */
@Component
@Slf4j
public class StandaloneProcessor implements BasicProcessor {


    @Override
    public ProcessResult process(TaskContext context) throws Exception {
        OmsLogger omsLogger = context.getOmsLogger();
        omsLogger.info("處理器啟動成功,context 是 {}.", context);


        log.info("單機處理器正在處理");
        log.info(context.getJobParams());


        omsLogger.info("處理器執行結束");


        boolean success = true;


        return new ProcessResult(success, context + ": " + success);
    }
}

執行結果

圖片圖片

廣播處理器:BroadcastProcessor

廣播執行的策略下,所有機器都會被調度執行該任務。為了便于資源的準備和釋放,廣播處理器在BasicProcessor 的基礎上額外增加了 preProcess 和 postProcess 方法,分別在整個集群開始之前/結束之后選一臺機器執行相關方法。代碼示例如下:

@Slf4j
@Component
public class BroadcastProcessorDemo implements BroadcastProcessor {


    @Override
    public ProcessResult preProcess(TaskContext context) throws Exception {
        OmsLogger omsLogger = context.getOmsLogger();
        omsLogger.info("預執行,會在所有 worker 執行 process 方法前調用");
        log.info("預執行,會在所有 worker 執行 process 方法前調用");
        // 預執行,會在所有 worker 執行 process 方法前調用
        return new ProcessResult(true, "init success");
    }


    @Override
    public ProcessResult process(TaskContext context) throws Exception {
        OmsLogger omsLogger = context.getOmsLogger();
        // 撰寫整個worker集群都會執行的代碼邏輯
        omsLogger.info("撰寫整個worker集群都會執行的代碼邏輯");
        log.info("撰寫整個worker集群都會執行的代碼邏輯");
        return new ProcessResult(true, "release resource success");
    }


    @Override
    public ProcessResult postProcess(TaskContext context, List<TaskResult> taskResults) throws Exception {


        // taskResults 存儲了所有worker執行的結果(包括preProcess)
        // 收尾,會在所有 worker 執行完畢 process 方法后調用,該結果將作為最終的執行結果
        OmsLogger omsLogger = context.getOmsLogger();
        omsLogger.info("收尾,會在所有 worker 執行完畢 process 方法后調用,該結果將作為最終的執行結果");
        log.info("收尾,會在所有 worker 執行完畢 process 方法后調用,該結果將作為最終的執行結果");
        return new ProcessResult(true, "process success");
    }
}

執行結果

圖片圖片

并行處理器:MapReduceProcessor

MapReduce 是最復雜也是最強大的一種執行器,它允許開發者完成任務的拆分,將子任務派發到集群中其他Worker 執行,是執行大批量處理任務的不二之選!實現 MapReduce 處理器需要繼承 MapReduceProcessor類,具體用法如下示例代碼所示:

@Slf4j
@Component
public class MapReduceProcessorDemo implements MapReduceProcessor {
    @Override
    public ProcessResult process(TaskContext context) throws Exception {
        final OmsLogger omsLogger = context.getOmsLogger();
        // 判斷是否為根任務
        if (isRootTask()) {


            // 構造子任務
            List<SubTask> subTaskList = Lists.newLinkedList();
            SubTask subTask=new SubTask();
            subTask.setSiteId(1L);
            subTask.setName("iron.guo");
            subTaskList.add(subTask);
            /*
             * 子任務的構造由開發者自己定義
             * eg. 現在需要從文件中讀取100W個ID,并處理數據庫中這些ID對應的數據,那么步驟如下:
             * 1. 根任務(RootTask)讀取文件,流式拉取100W個ID,并按1000個一批的大小組裝成子任務進行派發
             * 2. 非根任務獲取子任務,完成業務邏輯的處理
             */


            // 調用 map 方法,派發子任務(map 可能會失敗并拋出異常,做好業務操作)
            map(subTaskList, "DATA_PROCESS_TASK");
            omsLogger.info("執行根任務-派發子任務");
            return new ProcessResult(true, "ROOT_PROCESS_SUCCESS");
        }


        // 非子任務,可根據 subTask 的類型 或 TaskName 來判斷分支
        if (context.getSubTask() instanceof SubTask) {
            omsLogger.info("執行子任務開始");
            omsLogger.info("Get from SubTask : name is {} and id is {}",((SubTask) context.getSubTask()).getName(),((SubTask) context.getSubTask()).getSiteId());
            // 執行子任務,注:子任務人可以 map 產生新的子任務,可以構建任意級的 MapReduce 處理器
            return new ProcessResult(true, "PROCESS_SUB_TASK_SUCCESS");
        }


        return new ProcessResult(false, "UNKNOWN_BUG");
    }


    @Override
    public ProcessResult reduce(TaskContext taskContext, List<TaskResult> taskResults) {


        // 所有 Task 執行結束后,reduce 將會被執行
        // taskResults 保存了所有子任務的執行結果


        // 用法舉例,統計執行結果
        AtomicLong successCnt = new AtomicLong(0);
        taskResults.forEach(tr -> {
            if (tr.isSuccess()) {
                successCnt.incrementAndGet();
            }
        });
        // 該結果將作為任務最終的執行結果
        return new ProcessResult(true, "success task num:" + successCnt.get());
    }


    // 自定義的子任務
    @Getter
    @Setter
    @NoArgsConstructor
    @AllArgsConstructor
    private static class SubTask {
        private Long siteId;
        private String name;




    }


}

執行結果

圖片圖片

注:Map 處理器相當于 MapReduce 處理器的閹割版本(閹割了 reduce 方法),此處不再單獨舉例。

工作流

圖片圖片

點擊右上角按鈕 新建工作流,即可錄入新的工作流,具體界面和說明如下所示。

  • 工作流名稱:名稱,無實際業務用途,請盡量精簡字段
  • 工作流描述:描述,無實際業務用途,請盡量精簡字段
  • 定時信息:該工作流的觸發方式的觸發方式,包含時間表達式類型選擇框和時間表達式輸入框

CRON -> 填寫 CRON 表達式(在線生成網站)

API -> 不需要填寫任何參數,表明該任務由 OpenAPI 觸發

  • 生命周期:定時策略生效的時間段
  • 最大實例:該工作流同時執行的數量
  • 任務依賴關系:提供編輯界面可視化操作,繪制 DAG(有向無環圖),配置工作流內各個任務的依賴關系

DAG 操作指南

編輯依賴關系

v4.0.0 以后支持節點的自由拖拉拽,不用再點點點了,哈哈哈 ~

  • 添加節點:點擊 DAG 編輯框左上方的 “導入任務”,導入當前存在的任務(需要提前在 任務管理界面 錄入任務),生成 DAG 的節點
  • 連接節點:點擊起始節點的任意一個錨點摁住不放,拖動鼠標連接到另一個節點的任意一個錨點即可
  • 刪除節點:選中需要刪除的節點,按退格鍵( 注意:windows 下使用退格鍵 [Backspace],macOS 下使用刪除鍵 [delete] )
  • 刪除邊:選中需要刪除的邊,按退格鍵( 注意:windows 下使用退格鍵 [Backspace],macOS 下使用刪除鍵 [delete] )

導入任務節點

任務為之前創建的任務,可用工作流形式串聯起來執行。

圖片圖片

編輯節點信息

點擊需要編輯的節點,在右側會彈出一個編輯框,如下圖所示

圖片圖片

  • 任務名稱:當前節點引用的任務名稱,點擊可編輯(支持輸入名稱進行模糊搜索)
  • 節點名稱:節點的名稱,無實際業務用途,在能明確表示節點背后的業務邏輯的情況下請盡量精簡字段
  • 節點參數:節點的參數配置,當這個信息不為空的時候使用這個參數覆蓋當前節點所引用的任務所配置的參數信息
  • 是否啟用:未啟用的節點將會直接跳過
  • 失敗跳過:當這個節點執行失敗的時候不會打斷整個工作流的執行

特殊節點說明

判斷節點

圖片圖片

判斷節點 不允許失敗跳過以及禁用,節點參數中存儲的是 Groovy 代碼(執行 Groovy 代碼時會將當前工作流上下文作為 context 變量注入到代碼執行的上下文中),其執行結果僅能返回 "true" 或者 "false",同時判斷節點僅有且必須有兩條“輸出”路徑。會根據該代碼的執行結果決定下游需要執行的節點。這里處理的原則是, 僅 cancel 那些只能通過被 disable 掉的邊可達的節點

舉個兩個栗子,灰色代表相應的邊 或者 節點被 disable 或 cancel,菱形代表判斷節點,假定執行結果為 true

圖片圖片

case 3 以及 case 4 中的節點 3 都會被 cancel ,因為它只能通過節點 1 -> 節點 3 的邊可達(該邊的屬性為 false),但對于節點 5 而言,在 case 4 中因為判斷節點 2 的執行結果為 true ,那么其可以通過節點 2 -> 節點 5 的邊可達,所以不會被 disable 。

備注:如果需要根據上游節點的執行結果決定下游節點,可以將上游節點的執行結果注入上下文中,再在判斷節點中做相應的判斷。

工作流嵌套節點

圖片圖片

該節點代表對某個工作流的引用,節點的 jobId 屬性存儲的是工作流 id,其他屬性和普通的任務節點一致。不允許出現循環引用以及多級嵌套的情況,即嵌套節點中指向的工作流一定是一個不含嵌套節點的工作流。

執行到該節點時,如果該節點處于啟用狀態,那么將啟動該節點所引用工作流的一個新實例,待該實例執行完成后再同步更新該節點的狀態。

注意,創建子工作流時,會透傳當前的上下文作為工作流的實例參數,在子工作流執行完成時會合并子工作流的上下文至父工作流的上下文中。

重試子工作流不會聯動重試父工作流,但失敗的子工作流會隨著父工作流的重試而原地重試(不會生成新的實例)

責任編輯:武曉燕 來源: HELLO程序員
相關推薦

2022-12-29 08:32:50

xxl-job緩存Schedule

2022-01-27 08:44:58

調度系統開源

2023-01-04 09:23:58

2023-11-07 07:56:40

2025-05-26 09:31:23

2023-06-26 00:14:28

Openjob分布式任務

2019-07-19 15:51:11

框架選型分布式

2024-11-06 18:01:15

分布式任務調度組件

2020-06-23 10:22:58

GitHub代碼開發者

2024-09-09 08:11:12

2021-12-26 00:03:27

響應式編程異步

2022-09-23 13:57:11

xxl-job任務調度中間件

2019-11-15 10:16:27

分布式任務框架

2024-08-07 08:15:47

2020-09-29 19:20:05

鴻蒙

2020-07-17 09:33:39

CPU內存調度

2024-08-27 09:34:24

2025-06-27 09:31:25

2022-03-26 17:13:22

ElasticJobxxl-job分布式

2025-09-18 09:31:01

點贊
收藏

51CTO技術棧公眾號

www国产精品内射老熟女| 91九色对白| 一级片一级片一级片| 香蕉大人久久国产成人av| 香蕉乱码成人久久天堂爱免费| 久久综合九色99| 国产又黄又粗又猛又爽| 日韩午夜电影| 最近2019中文字幕mv免费看| 蜜桃视频无码区在线观看| 日韩大片免费观看| 亚洲欧洲精品一区二区三区不卡| 国产另类第一区| 中文字幕福利视频| 国产精品vip| 在线视频日韩精品| www.日本高清| 亚洲超碰在线观看| 欧美三级视频在线播放| 亚州av在线播放| 久久精品国产68国产精品亚洲| 日韩视频在线永久播放| 国产成人无码av在线播放dvd| 在线黄色网页| 国产精品网站导航| 精品日韩欧美| 国产夫妻自拍av| 日本成人在线不卡视频| 91黄色8090| 唐朝av高清盛宴| 日韩.com| 在线观看欧美日韩| 少妇毛片一区二区三区| 动漫视频在线一区| 欧美一区二区三区在| 伊人国产在线视频| 日本综合视频| 日本黄色一区二区| 日韩精品一区二区三区久久| 国产桃色电影在线播放| 亚洲欧美aⅴ...| 国产又大又长又粗又黄| av网站在线播放| 国产亚洲污的网站| 欧美大香线蕉线伊人久久国产精品| 成人免费视频国产免费麻豆| 国产老肥熟一区二区三区| 国产一区二区在线免费视频| 中国黄色一级视频| 蜜臀av性久久久久蜜臀aⅴ| 国产99视频精品免视看7| av资源免费观看| 国产一区导航| 欧洲亚洲免费在线| 国产无遮挡呻吟娇喘视频| 99在线精品视频在线观看| 韩剧1988免费观看全集| 国产精品美女毛片真酒店| 尤物在线精品| 欧美有码在线观看| 亚洲av中文无码乱人伦在线视色| 午夜亚洲一区| 国产精品96久久久久久又黄又硬| 无码人妻丰满熟妇区五十路| 日本不卡123| 成人久久18免费网站图片| 国产欧美第一页| 国产高清不卡一区| 国产欧美综合精品一区二区| 香蕉视频免费在线看| 久久久噜噜噜久久中文字幕色伊伊 | 欧美成人vr18sexvr| 性感美女一区二区三区| 任你躁在线精品免费| 亚洲美女久久久| 久久久久久国产免费a片| 99re66热这里只有精品8| 美女999久久久精品视频| 久久综合综合久久| 国产视频久久| 成人精品一区二区三区电影免费 | 韩日成人影院| 欧美伊人久久久久久久久影院| 国产又黄又猛的视频| 99久久香蕉| 亚洲男子天堂网| 登山的目的在线| 亚洲大胆av| 国产精品久久久久99| 国产av无码专区亚洲av| 91在线小视频| 免费看啪啪网站| 国产夫妻在线播放| 欧美色男人天堂| 一区二区三区四区影院| 久久不卡国产精品一区二区| 久色乳综合思思在线视频| 在线观看免费国产视频| 秋霞影院一区二区| 成人av免费在线看| 国产福利在线视频| 亚洲最新视频在线观看| 欧美伦理视频在线观看| 一区二区三区自拍视频| 一二美女精品欧洲| 日本a在线观看| 精品一区二区三区久久| 蜜桃臀一区二区三区| 91一区二区三区在线| 色激情天天射综合网| 国产精品果冻传媒| 欧美电影《睫毛膏》| 51久久精品夜色国产麻豆| 国产手机视频在线| 国产欧美精品区一区二区三区| 91黄色在线看| 国产精品国产亚洲精品| 一区二区欧美在线| 日韩精品一区二区av| 国产精品66部| 一区二区三区在线视频111| 国产高清不卡| 亚洲精品久久久久久久久久久久 | 国产成人精品无码免费看夜聊软件| 一本精品一区二区三区| 国产欧美韩国高清| 国产私人尤物无码不卡| 日韩欧美精品中文字幕| 国产xxxx视频| 亚洲一级一区| 超碰97国产在线| 国内外激情在线| 欧美日本在线看| 欧美亚洲色综久久精品国产| 美女尤物久久精品| 久久久久se| 三妻四妾完整版在线观看电视剧 | 老熟妇精品一区二区三区| 欧美二区不卡| 亚洲综合中文字幕68页| 中文字幕有码在线视频| 91精品国产综合久久福利软件| 亚洲一二三精品| 日韩和的一区二区| 日韩精品欧美专区| yw.尤物在线精品视频| 亚洲欧美在线第一页| 中文字幕黄色片| 久久嫩草精品久久久精品一| 欧美亚洲另类色图| 亚洲宅男一区| 国产精品免费视频xxxx| 在线免费黄色| 91精品国产综合久久福利| a级黄色片免费看| 成人动漫av在线| 日韩欧美亚洲天堂| 宅男在线一区| 国产精品男人的天堂| 成人亚洲性情网站www在线观看| 欧美性色综合网| 免费高清在线观看电视| 国产精品亚洲一区二区三区妖精 | 日韩欧美国产wwwww| 精品在线免费观看视频| 99久久久久免费精品国产 | 久久丫精品久久丫| 成人美女在线视频| 久久久久人妻精品一区三寸| 精品一级毛片| 51午夜精品| 黄色视屏在线免费观看| 亚洲欧洲xxxx| 一卡二卡三卡在线观看| 一区二区三区四区国产精品| 男人的天堂影院| 三级精品在线观看| 日本一级淫片演员| 粉嫩久久久久久久极品| 国产成人黄色av| 成人福利在线观看视频| 亚洲国产一区二区三区四区| 波多野结衣网站| 一区二区欧美在线观看| 一本加勒比北条麻妃| 奇米一区二区三区av| 麻豆映画在线观看| 色婷婷狠狠五月综合天色拍 | 一区二区三区四区高清视频 | 国产精品白浆| 国产精品久久久久免费a∨大胸 | av地址在线观看| 久久九九电影| 精品免费久久久久久久| 欧美女王vk| 99热国产免费| 国产第一亚洲| 欧美一区二区三区四区在线| 久久综合之合合综合久久| 亚洲精品ady| 国产女无套免费视频| 色天天综合色天天久久| 国产一级片网址| 国产精品女上位| 双性尿奴穿贞c带憋尿| 国内成人精品2018免费看| 国产免费一区二区三区视频| 中文字幕日韩一区二区不卡| 日韩av影视| 欧美黑白配在线| 亚洲一区二区三区视频播放| 欧美aaa视频| 欧美一区二区三区…… | 日本啊v在线| 精品久久一二三区| 一级黄色片免费| 在线一区二区三区四区五区| 久草视频精品在线| 亚洲视频免费在线观看| 亚洲成人网在线播放| 岛国一区二区在线观看| 国产女同无遮挡互慰高潮91| 免费观看日韩av| 人妻无码视频一区二区三区| 国产精品色网| 久草热视频在线观看| 欧美视频不卡| 真人做人试看60分钟免费| 91久久夜色精品国产按摩| 日韩欧美亚洲日产国产| 精品理论电影在线| 日本视频一区在线观看| 亚洲欧洲免费| 欧美性天天影院| 啪啪亚洲精品| 欧美一区二区三区精美影视| 女人丝袜激情亚洲| 久久精品二区| 男男gay无套免费视频欧美| 久久精品女人的天堂av| 欧美日韩直播| 欧美极品一区| 国产精品一区2区3区| 日韩亚洲不卡在线| 欧美系列电影免费观看| 日韩资源av在线| 俺要去色综合狠狠| 亚洲成人一区二区三区| 欧美综合久久| 亚洲av综合色区| 欧美激情一区| 久艹视频在线免费观看| 国产美女一区| jizz欧美激情18| 九色porny丨国产精品| 国产又黄又猛的视频| 国产精品18久久久久久久久久久久| 三上悠亚 电影| 不卡的看片网站| 中文字幕一二三四区| 日本一区二区在线不卡| 国产日产在线观看| 亚洲激情成人在线| 日本在线小视频| 在线看日韩精品电影| 亚洲网站在线免费观看| 91麻豆精品国产91久久久久久久久| 成人av无码一区二区三区| 亚洲缚视频在线观看| 久久国产精品高清一区二区三区| 在线观看精品国产视频| 1769免费视频在线观看| 91av福利视频| 国产精品天堂蜜av在线播放| 91视频在线免费观看| 欧美电影免费网站| 日韩久久在线| 欧美一区二区三区另类| 可以在线看的av网站| 日韩福利视频网| 杨幂一区二区国产精品| 91在线视频网址| 91高清免费看| 欧美三级免费观看| 亚洲一区中文字幕在线| 亚洲第一区第二区| 91这里只有精品| 久久久久国产一区二区三区| 亚洲欧美在线成人| 国产精品二区三区四区| 欧美在线观看视频一区| 农民人伦一区二区三区| 日本最新不卡在线| 极品白嫩的小少妇| 中文久久乱码一区二区| 日本熟妇乱子伦xxxx| 欧美日韩在线播| 完全免费av在线播放| 中国丰满熟妇xxxx性| 日韩电影在线观看网站| 亚洲黄色小说在线观看| 国产精品网站在线播放| 久草手机在线观看| 在线综合视频播放| 精品资源在线看| 性欧美xxxx交| 警花av一区二区三区| 日韩高清dvd| 亚洲黄色天堂| 亚洲少妇一区二区| 国产精品黄色在线观看| 中文字幕在线欧美| 亚洲大胆人体av| 亚洲淫性视频| 国产欧美日韩中文字幕| 久久超碰99| 免费看日本毛片| 国产成人啪免费观看软件| 国产欧美小视频| 91黄色免费看| 免费毛片在线| 91chinesevideo永久地址| 超碰97久久| 日韩亚洲欧美一区二区| 国产麻豆成人传媒免费观看| 呻吟揉丰满对白91乃国产区| 色综合久久久久久久久| 午夜视频免费在线| 久久久久久av| 中文无码日韩欧| 久艹在线免费观看| 国产成a人亚洲精品| 麻豆视频在线免费看| 欧美精品乱码久久久久久| 第九色区av在线| 国产精品成人观看视频国产奇米| 亚瑟一区二区三区四区| 黄色大片在线免费看| 99久久精品国产导航| 日操夜操天天操| 精品国产精品一区二区夜夜嗨| 成人看av片| 91香蕉国产在线观看| 亚洲午夜精品一区二区国产| 亚洲综合伊人久久| 1区2区3区国产精品| 97精品人妻一区二区三区在线| xxxxx91麻豆| 精品中文在线| 分分操这里只有精品| 99精品久久只有精品| av大全在线观看| 国产一区二区三区四区福利| 国产一区影院| 天天在线免费视频| 国产91对白在线观看九色| 日本亚洲色大成网站www久久| 亚洲激情第一页| 欧美三级网址| 亚洲一区三区电影在线观看| 国产中文一区二区三区| 免费看一级一片| 亚洲黄色成人网| 国产精品亚洲d| 操bbb操bbb| fc2成人免费人成在线观看播放| 国产剧情在线视频| www.亚洲一区| 国产精品nxnn| 手机在线看福利| 又紧又大又爽精品一区二区| 无码国产色欲xxxx视频| 国产91在线播放精品91| 久久久久久久久久久久久久| 秘密基地免费观看完整版中文| 欧美视频在线免费看| 亚洲视频tv| 国产精品v欧美精品∨日韩| 亚洲女人av| 国产中文av在线| 亚洲精品国产拍免费91在线| 精品九九久久| 九色自拍视频在线观看| 亚洲国产成人私人影院tom | 国产激情偷乱视频一区二区三区| 日韩污视频在线观看| 色多多国产成人永久免费网站| 一区中文字幕电影| www.色偷偷.com| 亚洲五月六月丁香激情| se在线电影| 国产视频一区二区三区四区| 美腿丝袜亚洲一区| 日本系列第一页| 久久精品久久久久久| 亚洲精品小区久久久久久| 亚洲AV无码久久精品国产一区| 日韩欧美亚洲综合| 视频在线这里都是精品| 日韩精品在在线一区二区中文|