全部產品
Search
文件中心

SchedulerX:Spring任務

更新時間:Jul 06, 2024

Spring定時任務為您在Java體系下提供了便捷的定時任務開放方式,但其便捷的同時也有很多企業化情境下的局限性。通過對接SchedulerX任務調度,可快速實現企業化運用的支援。

前提條件

接入指南

步驟一:添加pom依賴

以Spring Boot接入模式為例,應用程式的pom.xml檔案中添加依賴及啟動類。

schedulerx2.version使用用戶端最新版本。更多資訊,請參見用戶端發布記錄

<dependency>
  <groupId>com.aliyun.schedulerx</groupId>
  <artifactId>schedulerx2-spring-boot-starter</artifactId>
  <version>${schedulerx2.version}</version>
  <!--如果用的是logback,需要把log4j和log4j2排掉 -->
  <exclusions>
    <exclusion>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
    </exclusion>
    <exclusion>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
    </exclusion>
  </exclusions>
</dependency>

無論是已經使用Spring定時任務或初次使用,都需要在啟用類上保持@EnableScheduling註解開啟。如下所示:

@SpringBootApplication
@EnableScheduling /** 開啟Spring定時任務 */
public class SchedulerXWorkerApplication {
    public static void main(String[] args) {
        SpringApplication.run(SchedulerXWorkerApplication.class, args);
    }
}

/** Spring原生配置的定時任務類*/
@Service
public class SpringScheduledProcessor {
    @Scheduled(cron = "0/2 * * * * ?")
    public void hello() {
        logger.info(DateUtil.now() + " hello world. start");
        logger.info(DateUtil.now() + " hello world. end");
    }
}

對於新接入上述配置或已經滿足上述配置的使用者,SchedulerX 預設不會主動接管業務應用中原本的Spring定時任務,相應定時任務還是會由Spring容器進行調度,不影響原本已有的Spring定時任務運行。

步驟二:添加配置參數

後續業務需要讓SchedulerX任務調度平台來接管Spring定時任務的運行,則可以在Properties檔案中添加如下配置。

# 1、應用接入配置
spring.schedulerx2.endpoint=${endpoint}
spring.schedulerx2.namespace=${namespace}
spring.schedulerx2.groupId=${groupId}
spring.schedulerx2.appKey=${appKey}

# 2、啟用SchedulerX接管Spring定時任務
spring.schedulerx2.task.scheduling.scheduler=schedulerx

# 3、SchedulerX接管Spring定時任務,開啟自動同步任務;以下非必選參數
#spring.schedulerx2.task.scheduling.sync=true
#spring.schedulerx2.regionId=同步至目的地區域編號(關於RegionId請參見服務存取點)
#spring.schedulerx2.aliyunAccessKey=XXXXXXXXX
#spring.schedulerx2.aliyunSecretKey=XXXXXXXXX

配置說明:

  • 應用接入配置:登入分布式任務調度平台,在左側導覽列,單擊應用管理,在應用管理頁面下的操作欄選擇已建立的應用,單擊接入配置即可獲得接入配置資訊,如果是首次新接入需要建立一個應用分組。

  • 開啟自動同步任務配置:對於原本已使用Spring定時任務且存量定時任務較多的使用者,可以選擇在應用設定檔中開啟自動同步任務,大幅度簡化步驟三中的手動建立過程。配置中的RegionId請參見服務存取點中的地區ID。

重要

自動同步的任務為了保持與原生Spring任務在叢集環境中啟動並執行規則一致,預設同步至SchedulerX平台上的任務執行模式為廣播運行(即叢集中每台機器都會在相應時點執行該任務)。如果業務需要自動在叢集機器中選擇一個運行,可在控制台編輯相應任務的執行模式為單機運行。關於參數的詳細資料,請參見步驟三

步驟三:手動建立定時任務(可選)

說明

如果您在步驟二中配置了開啟自動同步任務,則不需要手動建立定時任務。

  1. 登入分布式任務調度平台

  2. 在左側導覽列,單擊任務管理

  3. 任務管理頁面,單擊建立任務。選擇SpringSchedule任務類型,配置對應定時任務類及其方法名。

    配置名稱

    意義

    任務名

    任務名稱。

    描述

    任務描述,盡量簡潔地描述業務,便於後續搜尋。

    應用ID

    任務所屬分組。可以在下拉式清單中選擇。

    任務類型

    指任務所實現的語言,當前支援Java、Shell、Python、Go、HTTP、Node.js、XXL-JOB和DataWorks類型,其中Shell、Python和Go會彈出編輯框,在編輯框中編寫任務指令碼。

    本文任務類型為SpringSchedule。

    spring schedule配置

    定時任務代碼的完整類名(class name)和任務的方法名(method name)。

    執行模式

    執行模式,這裡特指任務執行的模式,當前支援以下模式。

    • 單機運行:隨機選一台機器執行。

    • 廣播運行:所有機器同時執行並等待全部結束。

    說明

    當選擇了不同的執行模式後,進階設定中的參數會相應變化。

    優先順序

    同一應用下多個任務同時在一個執行個體中運行時,優先順序高的任務會被優先執行。但當一個應用中的多個任務在多個執行個體中運行時,不同優先順序的任務被調度到不同執行個體執行,可能導致低優先順序任務被優先執行。SchedulerX通過可搶佔的優先順序隊列規避了這種可能性,並保證同時在池子中等待的高優先順序任務被優先執行。更多資訊,請參見可搶佔的優先順序隊列

    任務參數

    任一字元串,可以在運行時通過上下文擷取。

  4. 配置對應定時觸發頻率。

    說明

    頻率會以控制台配置的頻率為準,Spring定時任務代碼中原生註解@Scheduled中配置將會失效,但該註解在代碼中需要保留。

    定時參數說明如下:

    配置名稱

    意義

    時間類型

    • none:無調度方式,一般通過工作流程觸發。

    • cron:Cron運算式。

    • api:通過API觸發。

    • fixed_rate:固定頻率。

    • second_delay:秒級固定延遲。

    • one_time:一次性任務。

    cron運算式(僅適用於cron時間類型)

    填寫Cron運算式。可以直接按照Cron文法填寫,也可以使用工具產生並驗證。

    固定頻率(僅適用於fixed_rate時間類型)

    填寫固定頻率,單位為秒,只支援60秒以上。例如200表示每200s調度一次。

    固定延遲(僅適用於second_delay時間類型)

    填寫固定延遲,單位為秒。範圍為1秒~60秒。例如5表示延遲5秒觸發調度。

    進階配置參數說明如下:

    配置名稱

    意義

    資料時間位移

    資料時間相對於調度時間的位移,可以在調度時從上下文擷取該值。

    時區

    可以根據實際情況選擇不同時區,包括一些常用國家或地區,也包括標準的GMT表達方式。

    日曆

    可選擇工作日或者金融日。

  5. 設定相關警示條件和通知渠道等。關於通知渠道,請參見通知連絡人和通知連絡人群組

    完成上述步驟後,SchedulerX 任務調度平台即可接管運行Spring的定時任務,支援為原生的Spring任務帶來的各種可視化管控、任務業務日誌查詢、執行鏈路查看、任務執行通知警示等企業級能力。

步驟四:驗證接入任務

  1. 啟動Spring應用,啟動成功之後。登入分布式任務調度平台,在左側導覽列單擊應用管理,查看如下對應應用分組的接入執行個體是否存在,即可說明已成功完成應用接入平台。

image

  1. 在控制台左側導覽列單擊任務管理,選擇操作欄對應的應用任務單擊運行一次,運行成功即可。

常見問題

SchedulerX接管後原Spring定時器依舊運行

由於應用中配置了自訂的Scheduler調度器導致SchedulerX覆蓋自訂處理器。請排查業務應用工程中是否存在實現org.springframework.scheduling.annotation.SchedulingConfigurer介面的類,確認是否調用了ScheduledTaskRegistrar的setScheduler方法覆蓋預設調度器,如果存在,請注釋掉相關邏輯即可。

Spring任務如何擷取任務上下文

在業務應用工程代碼中增加以下代碼擷取任務上下文。

JobContext jobContext = ContainerFactory.getContainerPool().getContext();

Spring任務是否支援返回結果

版本用戶端大於1.10.11時,Spring任務支援返回結果,您可以直接在定時方法上返回任意結果。

@Scheduled(cron = "0/5 * * * * ?")
public ProcessResult helloStandalone1() {
    try {
        logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. start");
        TimeUnit.SECONDS.sleep(2L);
        logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. end");
    } catch (Exception e) {
        e.printStackTrace();
        logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. exception end..");
    }
    return new ProcessResult(true, "執行結果資訊");
}

@Scheduled(cron = "0/5 * * * * ?")
public String helloStandalone2() {
    try {
        logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. start");
        TimeUnit.SECONDS.sleep(2L);
        logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. end");
    } catch (Exception e) {
        e.printStackTrace();
        logger.info(DateUtil.now() + " " + Thread.currentThread().getName() + " hello world. exception end..");
    }
    return "執行結果資訊";
}