xxl-job 調度中心如何進行進行任務調度


簡介

再看一遍 xxl-job 架構圖:
在這里插入圖片描述
調度中心主要提供了兩個功能: 系統管理 和 任務調度。其余的都是一些輔助功能。

  • 系統管理正如圖中所示的那樣, 包括任務管理、執行器管理、日志管理。還提供了管理界面。
  • 任務調度就是負責從數據中心拉取任務,並按照執行時間將任務投遞給執行器。

調度器的組成結構

在這里插入圖片描述

兩個核心線程

當調度中心啟動后,會啟動以下兩個線程:

  1. schedulerThread
    scheudlerThread主要做如下兩件事情:
  • 從數據中心(db),也就是 xxl_job_info表中掃描出符合 條件 1 的任務, 條件1 限制如下:
    • 任務執行時間 小於(當前時間 + 5 s)
    • 限制掃描個數, 這個值是動態的,會根據后面的提到的 快慢線程池 中線程數量有關系。
    count = treadpool-size * trigger-qps  (each trigger cost 50ms, qps = 1000/50 = 20) 
    
    treadpool-size = (getTriggerPoolFastMax() + getTriggerPoolSlowMax()) * 20
    // 看完快慢線程池的介紹,再回過頭來看這里,會更容易理解  
  • 掃描出來的任務被划分為以下 3 類:
  • 在這里插入圖片描述
  1. ringThread

ringThread的作用就是不斷從 容器 中讀取 當前時間點需要執行 的任務, 讀取出來的任務會交給一個叫 快慢線程池 的東西去將任務傳遞給調度器去執行。

時間輪

上述的 ringThread和 容器 共同組成了一個時間輪。

簡單來講,時間輪實現了 延遲執行 的功能,它在 xxl-job 中的作用就是讓 還未到達執行時間 的任務,按照預計的時間通過 快慢線程池 一個一個送到 執行器 中去執行。

  • 時間輪的數據結構一般是 數組 + 鏈表, 和 jdk1.7 中的 HashMap 是一個道理,鏈表中的每個節點就是一個待執行的任務。

  • xxl-job 中的時間輪可以形象描述為以下這張圖,像一個只有秒針的鍾表一樣。

  • ringThread 線程運行過程中,每秒會掃過一個刻度,假設當前刻度位置存在 job 鏈表,就把鏈表中的所有 job 取出來,最后丟給 快慢線程池。

  • 當然 xxl-job 為了避免處理耗時太長,會跨過刻度,多向前校驗一個刻度;也就是當指針指到 2s 時,會把 1s 和 2s 位置的任務同時讀取出來。
    在這里插入圖片描述

快慢線程池

上面提到任務從數據中心掃描出來后,隨之就會被丟到快慢線程池中,快慢線程池的定義如下:

fastTriggerPool = new ThreadPoolExecutor(
                10,
                XxlJobAdminConfig.getAdminConfig().getTriggerPoolFastMax(),
                60L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(1000),
                new ThreadFactory() {
                    @Override
                    public Thread newThread(Runnable r) {
                        return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-fastTriggerPool-" + r.hashCode());
                    }
                });

        slowTriggerPool = new ThreadPoolExecutor(
                10,
                XxlJobAdminConfig.getAdminConfig().getTriggerPoolSlowMax(),
                60L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(2000),
                new ThreadFactory() {
                    @Override
                    public Thread newThread(Runnable r) {
                        return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-slowTriggerPool-" + r.hashCode());
                    }
                });

由上可知, 快慢線程池包含了兩個線程池 fast 和 slow,當一個 job 提交到快慢線程池后,快慢線程池會根據一些條件, 選擇其中一個線程池去執行后續的操作。

快慢線程池的作用如下:

實現線程池隔離:調度線程池進行隔離拆分,慢任務自動降級進入”Slow”線程池,避免耗盡調度線程,提高系統穩定性;

什么是慢任務?

如果一個任務在 1 分鍾內,它的執行超時次數超過 10 次,就被歸為 慢任務

當具體的快或者慢線程池接收到調度任務時,會通過 RPC 遠程調用去觸發 執行器 完成任務的執行邏輯。

源碼入口

com.xxl.job.admin.core.thread.JobScheduleHelper#start

com.xxl.job.admin.core.thread.JobTriggerPoolHelper#addTrigger

com.xxl.job.core.biz.client.ExecutorBizClient#run

總結

本文基於 xxl-job v2.x 的源碼分析了 xxl-job 調度器的組成結構 以及 調度中心是如何觸發任務的。

調度器主要包含了以下模塊:

  • schedulerThread: 負責從數據中心掃描需要執行的任務
  • ringThread: 負責精准地控制預計需要執行的任務
  • 快慢線程池:通過包裝兩個線程池,去分別執行 快任務 和 慢任務 的調度過程。

時間輪附錄

https://www.cnblogs.com/yuarvin/p/14445613.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM