全部產品
Search
文件中心

SchedulerX:任務常見問題

更新時間:Jul 16, 2026

本文介紹如何處理使用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被某切面代理,例如一些使用者間接引入一個錯誤的二方庫導致該現象,排除掉即可。

ProxyFactory 日誌中可以看到 TrackerInterceptorFilter 作為額外的切面代理導致 Bean 類型不符:

org.springframework.aop.framework.ProxyFactory: 1 interfaces [com.alibaba.schedulerx.worker.processor.JobProcessor]; 1 advisors [org.springframework.aop.support.DefaultPointcutAdvisor: pointcut [Pointcut.TRUE]; advice [com.alibaba.onetouch.tracker.filter.TrackerInterceptorFilter@7dc779bb]]; targetSource [SingletonTargetSource for target object [com.alibaba.onetouch.lc.dts.presentation.LcForexMessageRedoJob@11087483]]; proxyTargetClass=false; optimize=false; opaque=false; exposeProxy=false; frozen=false

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

任務失敗,報錯“Unable to make field 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已經不存在,則無需處理。

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

問題現象

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

可能原因

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

解決方案

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

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

  • 登入業務機器,開啟~/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
    $jstack 29191 |grep 58903617 -A 200
    "Schedulerx-Container-Thread-58903617-0" #4093 prio=5 os_prio=0 tid=xxx               nid=xxx    waiting on condition [0x00002ad443101000]
       java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x000000072b837ae0> (a java.util.concurrent.CountDownLatch$Sync)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
    at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)
    at com.aliyun.ticket.importworker.WOImportJob.startImport(WOImportJob.java:353)
    at com.aliyun.ticket.importworker.WOImportJob.doImportForAll(WOImportJob.java:242)
    at com.aliyun.ticket.importworker.WOImportJob.process(WOImportJob.java:163)
    at com.alibaba.schedulerx.worker.container.ThreadContainer.start(ThreadContainer.java:90)
    at com.alibaba.schedulerx.worker.container.ThreadContainer.run(ThreadContainer.java:60)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:756)
    
    "Container-Batch-Statues-Retrieve-Thread-58903617" #4092 prio=5 os_prio=0 tid=xxx               nid=xxx    waiting on condition [0x00002ad44fe0e000]
       java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)
    at com.alibaba.schedulerx.worker.batch.BaseReqHandler$2.run(BaseReqHandler.java:74)
    at java.lang.Thread.run(Thread.java:756)
    
    "TDDL-Druid-ConnectionPool-DestroyScheduler--2-thread-237" #4052 daemon prio=5 os_prio=0 tid=xxx               nid=xxx    waiting on condition [0x00002ad462e00000]
       java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000007436c7190> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.poll(ScheduledThreadPoolExecutor.java:1129)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.poll(ScheduledThreadPoolExecutor.java:809)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1066)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

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

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

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

問題現象

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

可能原因

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

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

解決方案

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

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

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

任務預設並發是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,然後單擊繁忙,即可查看超過了閾值的指標。

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

執行個體繁忙配置地區包含以下閾值:

  • load5:預設值為 0

  • 記憶體使用量率:預設值為 90%

  • 磁碟使用率:預設值為 95%

  • 是否觸發繁忙機器:預設開啟

如果是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及以上版本該現象會得到最佳化。

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

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

彈框中還包含指定機器欄位,可通過下拉框選擇啟動並執行執行個體。底部提示:執行個體參數不會覆蓋任務參數。

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

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

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

詳細代碼如下所示。

@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);
    }

}