知識庫 / Spring / Spring Boot RSS 訂閱

Spring 中後台任務與 JobRunr

Spring Boot
HongKong
4
12:46 PM · Dec 06 ,2025

1. 概述

在本教程中,我們將探討使用 JobRunr 在 Java 中進行分佈式後台任務調度和處理,並將其與 Spring 集成。

2. 關於 JobRunr

JobRunr 是一個我們可以嵌入到我們應用程序中的庫,它允許我們使用 Java 8 lambda 安排後台任務。我們可以使用我們現有的 Spring 服務中的任何方法來創建任務,而無需實現接口。一個任務可以是短的也可以是長時間運行的,並且它會被自動卸載到後台線程中,以避免當前 Web 請求被阻塞。

為了完成任務,JobRunr 會分析 Java 8 lambda,將其序列化為 JSON,並將其存儲到關係型數據庫或 NoSQL 數據存儲中。

3. JobRunr 的特性

如果我們的系統產生過多的後台任務,並且服務器負載過高,我們可以輕鬆地通過添加更多應用程序實例來進行水平擴展。JobRunr 將自動分擔負載,並將所有任務分發到我們應用程序的不同實例上。

它還包含一個帶有指數退避策略的自動重試功能,用於處理失敗的任務。此外,JobRunr 還內置了一個儀表盤,允許我們監控所有任務。JobRunr 具有自我維護功能——成功完成的任務將在可配置的時間後自動刪除,因此無需手動執行存儲清理。

4. 安裝配置

為了簡化操作,我們將使用內存數據存儲來存儲所有與工作相關的資料。

4.1. Maven 配置

讓我們直接進入 Java 代碼。但在進行之前,我們需要在我們的 <em >pom.xml</em> 文件中聲明以下 Maven 依賴

<dependency>
    <groupId>org.jobrunr</groupId>
    <artifactId>jobrunr-spring-boot-starter</artifactId>
    <version>5.1.7</version>
</dependency>

4.2. Spring Integration

在直接開始創建後台任務之前,我們需要初始化 JobRunr。由於我們使用了 jobrunr-spring-boot-starter 依賴項,這非常簡單。我們只需要在 application.properties 中添加一些屬性即可:

org.jobrunr.background-job-server.enabled=true
org.jobrunr.dashboard.enabled=true

第一個屬性告訴 JobRunr 我們想要啓動一個 BackgroundJobServer 實例,該實例負責處理作業。第二個屬性告訴 JobRunr 啓動嵌入式儀表盤。

默認情況下,jobrunr-spring-boot-starter 將嘗試使用您現有的 DataSource 以便在關係數據庫中存儲所有作業相關的信息。

但是,由於我們將會使用內存數據存儲,因此我們需要提供一個 StorageProvider Bean:

@Bean
public StorageProvider storageProvider(JobMapper jobMapper) {
    InMemoryStorageProvider storageProvider = new InMemoryStorageProvider();
    storageProvider.setJobMapper(new JobMapper(new JacksonJsonMapper()));
    return storageProvider;
}

5. 使用方法

現在,讓我們瞭解如何使用 JobRunr 在 Spring 中創建和安排後台任務。

5.1. 注入依賴

當我們需要創建任務時,我們需要注入 <a href="https://www.javadoc.io/doc/org.jobrunr/jobrunr/latest/org/jobrunr/scheduling/JobScheduler.html">JobScheduler</a> 以及我們現有的 Spring 服務,其中包含我們想要創建任務的方法,在本例中是 <em>SampleJobService</em>

@Inject
private JobScheduler jobScheduler;

@Inject
private SampleJobService sampleJobService;

JobScheduler 類來自 JobRunr,允許我們排隊或安排新的後台任務。

SampleJobService 可以是我們在 Spring 中現有的任何服務,該服務包含一個可能在 Web 請求中耗費過多的方法。 還可以是調用其他外部服務的任何方法,以便我們可以在 JobRunr 遇到異常時重試該方法,從而增加彈性。

5.2. 創建後台運行任務

現在我們已經定義了依賴項,可以使用 enqueue 方法創建後台運行任務:

jobScheduler.enqueue(() -> sampleJobService.executeSampleJob());

函數可以有參數,就像任何其他 lambda 函數一樣:

jobScheduler.enqueue(() -> sampleJobService.executeSampleJob("some string"));

此行確保 lambda –包括類型、方法和參數– 被序列化為 JSON 並持久化到存儲(例如,RDBMS,如 Oracle、Postgres、MySQL 或 MariaDB,或 NoSQL 數據庫)。

多個 BackgroundJobServer 中的線程池將立即以先進先出(FIFO)的方式執行這些排隊的後台任務。 JobRunr 通過樂觀鎖機制保證你的任務由單個工作進程執行。

5.3. 將作業安排為未來

我們可以使用 schedule 方法將作業安排為未來:

jobScheduler.schedule(LocalDateTime.now().plusHours(5), () -> sampleJobService.executeSampleJob());

5.4. 週期性調度任務

如果需要週期性執行任務,則需要使用 scheduleRecurrently 方法:

jobScheduler.scheduleRecurrently(Cron.hourly(), () -> sampleJobService.executeSampleJob());

5.5. 使用 <em @Job 註解進行標註

為了控制所有作業方面,我們可以使用 <em @Job 註解標註我們的服務方法。這允許我們在儀表板中設置顯示名稱,並在作業失敗時配置重試次數。

@Job(name = "The sample job with variable %0", retries = 2)
public void executeSampleJob(String variable) {
    ...
}

我們甚至可以使用通過 String.format() 語法傳遞給我們的任務的變量,顯示名稱中。

如果我們在特定用例中想要僅在特定異常情況下重試某個任務,我們可以編寫自定義的 ElectStateFilter,其中我們能夠訪問 Job 並且完全控制如何繼續執行。

6. 儀表盤

JobRunr 內置了一個儀表盤,允許我們監控所有任務。 您可以在 http://localhost:8000 找到它,並檢查所有任務,包括所有重複任務以及處理所有排隊的任務所需的時間的估算。

事情可能會出錯,例如,SSL 證書過期或磁盤已滿。 JobRunr 默認情況下將使用指數退避策略重新安排後台任務。 如果後台任務失敗 10 次,才會進入 失敗 狀態。 然後您可以決定在根原因解決後重新排隊失敗的任務。

所有這些都可以在儀表盤中查看,包括每個重試的精確錯誤消息以及任務失敗的原因的完整堆棧跟蹤。

7. 結論

在本文中,我們使用 JobRunr 和 jobrunr-spring-boot-starter 構建了我們的第一個基本調度器。 本教程的關鍵要點是,我們只需一行代碼就能創建任務,並且無需基於 XML 的配置或實現接口。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.