全部產品
Search
文件中心

SchedulerX:任務常見問題

更新時間:Aug 16, 2024

本文介紹如何處理使用SchedulerX過程中的一些任務管理問題。

Spring應用找不到Bean怎麼辦?

  1. 通過應用管理串連機器查看啟動方式,確保為Spring或者Spring Boot方式。

  2. JobProcessor要注入為bean,比如加@Component註解。

  3. 排查Pom依賴如果依賴spring-boot-devtools則需要排除掉。

  4. 如果JobProcessor和process方法有aop註解,需要升級到最新版本SchedulerX用戶端,低版本不支援aop。

  5. 因為多加了一層代理導致Bean類型不符。可以把斷點放入DefaultListableBeanFactory類中。其中beanDefinitionNames成員變數是Spring註冊的Bean列表, 裡面可以看到Bean被某切面代理,例如一些使用者間接引入一個錯誤的二方庫導致該現象,排除掉即可。

1

如果以上方案無法解決問題,可以調試ThreadContainer.start方法。如果class.forName報錯,class又確實存在,可能是業務方使用了某些架構,導致classLoader不一致,可以通過設定SchedulerxWorker.setClassLoader解決。

任務失敗,報錯“Unable to make fileld private”

MapReduce用到了序列化和還原序列化架構,從 Java 9 版本開始,反射私人變數需要手動開啟。請在JVM參數中添加以下配置:

--add-opens java.base/java.lang=ALL-UNNAMED

任務失敗,報錯“submit jobInstanceId to worker timeout”

當應用發布的時候報該問題或者偶爾報該問題時,無需處理。

如果持續報錯且每次報錯的workerAddr都是同一台機器,說明服務端和用戶端長串連斷開,需要將該Worker節點重啟或者升級SchedulerX用戶端版本至最新版本。升級至最新版本後,斷開的長串連可自動回復。

任務失敗,報錯“used space beyond 90.0%!”

磁碟已滿,需要清理ECS或者容器上的磁碟空間。

任務失敗,報錯“ClassNotFoundException”

說明執行任務的Worker上沒有該類,請確保Java任務配置的Processor類名必須是類的全路徑,並非簡寫。

如果配置的jobProcessor類名正確,即為Worker上沒有該類,一般為使用者發錯包或者該應用還串連了其他人的機器。您可以自己登入Worker機器,通過反編譯查看詳細情況。

任務失敗,報錯“jobInstance=xxx don't update progress more than 60s”

正在運行任務的Worker停止工作或者發布時,超過60秒沒有彙報進度時,會被服務端強制終止。如果確定問題由Worker引入或者該Worker已經不存在,則無需處理。

任務執行失敗,且沒有錯誤資訊

問題現象:

任務執行失敗,且沒有錯誤資訊。

可能原因:

機器或商務邏輯執行失敗等。

解決方案:

  • 執行列表頁面,選擇任務執行個體列表,在任務執行個體列表欄,選擇對應的任務,單擊操作列下的詳情,進入任務執行個體詳情,查看對應執行失敗的機器。

    如果沒有子任務詳情,說明為簡單任務。查看基本資料的workAddr,該機器為執行任務的業務機器。

  • 登入業務機器,開啟~/logs/schedulerx/worker.log日誌。

    執行grep <執行個體ID> worker.log查看該執行個體相關的日誌。如果有ERROR層級異常,查看堆棧的具體原因。

  • 錯誤描述為空白則基本為商務邏輯執行失敗且未返回失敗資訊,請先自行排查商務邏輯。

  • 錯誤描述有架構異常,請加入釘群(釘群號:23103656)聯絡SchedulerX技術支援人員。

如何排查任務失敗的原因?

  • 如果是單機任務,業務直接拋異常,可以在執行列表頁面,單擊任務執行個體列表,在對應任務執行個體的操作列,單擊詳情查看錯誤資訊。

  • 如果任務沒有拋異常或者使用了分布式任務,您的專業版應用可以通過Log Service來排查問題。

  • 如果是基礎版應用,您可以自行登入Worker節點,查看SchedulerX的日誌和業務自己的日誌進行排查。

任務運行中卡住怎麼辦?

問題現象:

調度任務一直處於執行中,不能結束。

可能原因:

  • 業務的問題。

  • SchedulerX的問題。

解決方案:

業務方面的問題可以按照以下方案排查,其他問題請加入釘群(釘群號:23103656)聯絡SchedulerX技術支援人員。

  • 專業版應用:可以通過控制台的查看堆棧功能(1.4.2及以上用戶端版本可用),來排查任務異常的堆棧。

  • 基礎版應用:可以自行登入卡住的Worker節點,通過jstack命令查看堆棧,執行命令。

    jstack <pid> | grep <任務執行個體id> -A 20

    6

如何排查任務運行慢的原因?

開啟專業版,使用鏈路追蹤。具體操作,請參見如何接入鏈路追蹤

任務運行執行個體達到上限怎麼辦?

問題現象:

在任務管理頁面,單擊運行一次,收到任務運行執行個體達到上限,請稍後重試提示。

可能原因:

  • 該任務已經有任務執行個體在運行中。

  • 運行中的任務執行個體達到任務配置的最大並發數。

解決方案:

如果並發數合理,無需處理。可以在任務管理頁面,單擊更多 > 記錄查看運行中的任務執行個體

如果不合理,在目標任務的操作列,單擊編輯,在進階配置裡設定執行個體並發數

任務上一次沒運行完,下一次是排隊還是不運行了?

任務預設並發是1,即串列跑。如果任務執行時間比較長,上一次沒運行完,下一次調度時間到了,則下一次會直接丟棄,不會運行也不會排隊。

如果設定任務執行個體並發數為2,上一次沒運行完,下一次時間到了仍然可以運行一個執行個體,最多同時運行兩個任務執行個體。

如何設定一次性任務?

SchedulerX 2.0支援設定一次性任務。時間類型選擇one_time即可。一次性任務不保留任務執行記錄。

one_time任務運行完成後怎麼查看記錄?

one_time任務運行完會自動銷毀,防止資料堆積,且不保留任何記錄。如果需要儲存記錄,您可以開啟Log Service,保留最近兩周所有任務的執行日誌,方便排查問題。關於如何開啟Log Service,請參見應用管理

如何進行秒層級調度?

SchedulerX支援秒層級調度。cron、fix_rate不支援秒層級調度,您可以選擇時間類型為second_delay,即上一次運行完之後間隔幾秒再運行。

某個時間點沒有調度怎麼辦?

某個單機任務有一個時間點沒有調度運行時,您需要確認機器列表是否存在機器,並確認機器是否全部處於繁忙狀態。如果不存在機器,按無可用機器或機器繁忙進行排查。更多資訊,請參見無可用機器(no worker available)機器繁忙(all workers are busy)該怎麼辦?

建議為任務配置無可用機器警示。具體操作,請參見任務管理

SchedulerX如何設定逾時時間?

SchedulerX不支援子任務層級的逾時時間,只支援整個任務的逾時。可以通過控制台動態修改逾時時間。具體操作,請參見任務管理

為什麼執行個體停止之後還會執行?

問題現象:

執行個體停止之後仍然執行。

可能原因:

任務執行個體停止後,SchedulerX會把Kill訊息發送到用戶端。用戶端接收到Kill訊息後,會停止下發和停止執行未執行的子任務、銷毀該執行個體的上下文、銷毀執行個體所有的線程池。對於已經在執行中的子任務不會被停止掉,只會中斷對應的線程,所以子任務會繼續運行直到結束。

解決方案:

  • 一般情況下,您無需處理,等待子任務執行結束即可。

  • 如果確實需要停止後立即結束所有運行中的任務,需要修改子任務處理邏輯,增加對當前線程Interrupt狀態的處理。

如何進行任務管理進階配置?

更多資訊,請參見任務管理進階配置參數說明

機器繁忙(all workers are busy)該怎麼辦?

可以在應用管理頁面查看執行個體,定位繁忙狀態的Worker,然後單擊繁忙,即可查看超過了閾值的指標。

11

繁忙的閾值在應用管理頁面通過編輯應用分組配置。

1

如果是load繁忙,您需要查看自己是否為容器(K8s)部署。如果為容器(K8s)部署,需要配置以下兩個參數,否則採集的CPU使用率可能不準確。具體操作,請參見Spring Boot應用接入SchedulerX

key

描述

設定值

起始版本

spring.schedulerx2.enableCgroupMetrics

是否使用cgroup統計用戶端執行個體的指標。容器(K8s)環境需要自己手動開啟。

true/false,預設false。

1.2.2.2

spring.schedulerx2.cgroupPathPrefix

容器內cgroup的路徑。

預設是/sys/fs/cgroup/cpu/,如果存在該路徑則不需要設定。

1.2.2.2

如何接入鏈路追蹤?

任務調度支援全鏈路追蹤。具體操作,請參見如何接入鏈路追蹤

應用發布過程,任務執行卡住或變慢

問題現象:

應用發布過程,任務執行卡住或變慢。

可能原因:

對於分布式任務,處理子任務的機器下線會進行重新分發並輪詢檢查機器是否線上,會導致整個處理過程變慢。

解決方案:

將用戶端升級至最新版本,1.7.9及以上版本該現象會得到最佳化。

單擊運行一次後,系統提示輸入執行個體參數,如何處理?

任務管理頁面的操作列,單擊運行一次,可以執行一次該調度任務。彈框中的執行個體參數非必填,主要用於測試。

1

單擊運行一次並輸入執行個體參數,那麼代碼中擷取的是執行個體參數還是任務參數?

執行個體參數與任務參數是兩個不同的概念,代碼中具體擷取的參數是由使用者的業務代碼決定的。

如何擷取任務參數或者執行個體參數?

詳細代碼如下所示。

@Component
public class JavaDemoProcessor extends JavaProcessor {


    private static final Logger LOGGER = LoggerFactory.getLogger("schedulerxLog");


    @Override
    public ProcessResult process(JobContext jobContext) throws InterruptedException {

        LOGGER.info(JSON.toJSONString(jobContext));
        //擷取任務參數
        String jobParameters = jobContext.getJobParameters();
        //擷取執行個體參數
        String instanceParameters = jobContext.getInstanceParameters();
        LOGGER.info("任務參數:" + jobParameters);
        LOGGER.info("執行個體參數" + instanceParameters);
        return new ProcessResult(InstanceStatus.SUCCESS);
    }

}

如何?填寫執行個體參數後,代碼預設擷取執行個體參數,未填寫則擷取任務參數

詳細代碼如下所示。

@Component
public class JavaDemoProcessor extends JavaProcessor {

    private static final Logger LOGGER = LoggerFactory.getLogger("schedulerxLog");

    @Override
    public ProcessResult process(JobContext jobContext) throws InterruptedException {
        String params = null;
        if (StringUtils.isNotBlank(jobContext.getInstanceParameters())) {
            params = jobContext.getInstanceParameters();
        } else {
            params = jobContext.getJobParameters();
        }
        LOGGER.info("JavaDemoProcessor params:{}", params);
        return new ProcessResult(InstanceStatus.SUCCESS);
    }

}