Spring Batch 6 中的新功能
本節重點介紹 Spring Batch 6.0 的主要變化。有關完整的更改列表,請參閱發行說明。
Spring Batch 6.0 包含以下特性和改進:
依賴升級
在此主要版本中,Spring 依賴項已升級到以下版本:
-
Spring Framework 7.0
-
Spring Integration 7.0
-
Spring Data 4.0
-
Spring LDAP 4.0
-
Spring AMQP 4.0
-
Spring Kafka 4.0
-
Micrometer 1.16
批處理基礎設施配置改進
批處理基礎設施配置的新註解和類
在 v6 之前,@EnableBatchProcessing 註解與基於 JDBC 的基礎設施繫結。現在不再是這樣了。引入了兩個新註解來配置底層作業倉庫:@EnableJdbcJobRepository 和 @EnableMongoJobRepository。
從 v6 開始,@EnableBatchProcessing 允許您配置批處理基礎設施的公共屬性,而特定於儲存的屬性可以使用新的專用註解指定。
以下是使用這些註解的示例:
@EnableBatchProcessing(taskExecutorRef = "batchTaskExecutor")
@EnableJdbcJobRepository(dataSourceRef = "batchDataSource", transactionManagerRef = "batchTransactionManager")
class MyJobConfiguration {
@Bean
public Job job(JobRepository jobRepository) {
return new JobBuilder("job", jobRepository)
// job flow omitted
.build();
}
}
同樣,基於 DefaultBatchConfiguration 的程式設計模型也進行了更新,引入了兩個新的配置類來定義特定於儲存的屬性:JdbcDefaultBatchConfiguration 和 MongoDefaultBatchConfiguration。這些類可用於以程式設計方式配置每個作業倉庫的特定屬性以及其他批處理基礎設施 Bean。
預設情況下為無資源批處理基礎設施
DefaultBatchConfiguration 類已更新,預設情況下提供“無資源”批處理基礎設施(基於 v5.2 中引入的 ResourcelessJobRepository 實現)。這意味著它不再需要記憶體資料庫(如 H2 或 HSQLDB)作為作業倉庫,而這以前是批處理元資料儲存所必需的。
此外,當不使用元資料時,此更改將提高批處理應用程式的預設效能,因為 ResourcelessJobRepository 不需要任何資料庫連線或事務。
最後,此更改將有助於減少批處理應用程式的記憶體佔用,因為不再需要記憶體資料庫來儲存元資料。
批處理基礎設施配置簡化
在 v6 之前,非平凡的 Spring Batch 應用程式的典型配置非常複雜,需要大量的 Bean:JobRepository、JobLauncher、JobExplorer、JobOperator、JobRegistry、JobRegistrySmartInitializingSingleton 等。這需要大量的配置程式碼,例如需要在 JobRepository 和 JobExplorer 上配置相同的執行上下文序列化器。
在此版本中,為了簡化批處理基礎設施配置,進行了一些更改:
-
JobRepository現在擴充套件了JobExplorer介面,因此無需定義單獨的JobExplorerBean。 -
JobOperator現在擴充套件了JobLauncher介面,因此無需定義單獨的JobLauncherBean。 -
JobRegistry現在是可選的,並且足夠智慧,可以自動註冊作業,因此無需定義單獨的JobRegistrySmartInitializingSingletonBean。 -
事務管理器現在是可選的,如果沒有提供,則使用預設的
ResourcelessTransactionManager。
這減少了典型批處理應用程式所需的 Bean 數量,並簡化了配置程式碼。
面向塊處理模型的新實現
這不是一個新功能,而是面向塊處理模型的新實現。這個新實現作為實驗性新增在 5.1 版本中引入,現在在 6.0 版本中穩定可用。
新實現由 ChunkOrientedStep 類提供,它是 ChunkOrientedTasklet / TaskletStep 類的替代品。
以下是使用其構建器定義 ChunkOrientedStep 的示例:
@Bean
public Step chunkOrientedStep(JobRepository jobRepository, ItemReader<Person> itemReader, ItemWriter<Person> itemWriter) {
int chunkSize = 100;
return new ChunkOrientedStepBuilder<Person, Person>("step", jobRepository, chunkSize)
.reader(itemReader)
.writer(itemWriter)
.build();
}
此外,容錯功能也進行了如下調整:
-
重試功能現在基於 Spring Framework 7 中引入的重試功能,而不是之前的 Spring Retry 庫。
-
跳過功能已稍微適應新實現,現在僅完全基於
SkipPolicy介面。
以下是使用新的 ChunkOrientedStep 的重試和跳過功能的快速示例:
@Bean
public Step faulTolerantChunkOrientedStep(JobRepository jobRepository, ItemReader<Person> itemReader, ItemWriter<Person> itemWriter) {
// retry policy configuration
int maxRetries = 10;
var retrybaleExceptions = Set.of(TransientException.class);
RetryPolicy retryPolicy = RetryPolicy.builder()
.maxRetries(maxRetries)
.includes(retrybaleExceptions)
.build();
// skip policy configuration
int skipLimit = 50;
var skippableExceptions = Set.of(FlatFileParseException.class);
SkipPolicy skipPolicy = new LimitCheckingExceptionHierarchySkipPolicy(skippableExceptions, skipLimit);
// step configuration
int chunkSize = 100;
return new ChunkOrientedStepBuilder<Person, Person>("step", jobRepository, chunkSize)
.reader(itemReader)
.writer(itemWriter)
.faultTolerant()
.retryPolicy(retryPolicy)
.skipPolicy(skipPolicy)
.build();
}
有關如何從以前的實現遷移到新實現的更多詳細資訊,請參閱遷移指南。
新的併發模型
在此版本之前,基於“並行迭代”概念的併發模型需要在不同級別進行大量狀態同步,並且在節流和反壓方面存在一些限制,導致事務語義混亂和效能不佳。
此版本重新審視了該模型,並提供了一種基於生產者-消費者模式的新的、簡化的併發方法。併發面向塊的步驟現在在生產者執行緒和消費者執行緒之間使用有界內部佇列。一旦專案準備好處理,它們就會被放入佇列中,消費者執行緒一旦專案可用就從佇列中獲取專案。一旦塊準備好寫入,生產者執行緒就會暫停,直到塊寫入完成,然後恢復生產專案。
這種新模型更高效、更容易理解,併為併發執行提供了更好的效能。
新的命令列運算子
Spring Batch 從版本 1 開始就提供了 CommandLineJobRunner。雖然這個執行器多年來很好地完成了它的任務,但它在可擴充套件性和定製性方面開始顯現出一些限制。許多問題,例如靜態初始化、處理選項和引數的非標準方式、缺乏可擴充套件性等都被報告過。
此外,所有這些問題使得在 Spring Boot 中無法重用該執行器,這導致兩個專案中都存在重複程式碼以及行為分歧(例如作業引數遞增器行為差異),這讓許多使用者感到困惑。
此版本引入了 CommandLineJobRunner 的現代版本,名為 CommandLineJobOperator,它允許您從命令列操作批處理作業(啟動、停止、重啟等),並且是可定製、可擴充套件的,並已更新以適應 Spring Batch 6 中引入的新更改。
恢復失敗的作業執行能力
在此版本之前,如果作業執行突然失敗,無法在沒有手動資料庫更新的情況下恢復。這容易出錯,並且在不同的作業倉庫中不一致(因為它需要 JDBC 資料庫的一些 SQL 語句和 NoSQL 儲存的一些自定義語句)。
此版本在 JobOperator 介面中引入了一個名為 recover 的新方法,允許您在所有作業倉庫中一致地恢復失敗的作業執行。
停止所有型別步驟的能力
截至 v5.2,只能透過 JobOperator#stop 外部停止 Tasklet 步驟。如果自定義 Step 實現想要處理外部停止訊號,它就不能。
此版本添加了一個名為 StoppableStep 的新介面,它擴充套件了 Step,並且可以由任何能夠處理停止訊號的步驟實現。
優雅停機支援
Spring Batch 6.0 引入了對批處理作業優雅停機的支援。此功能允許您以受控方式停止正在執行的作業執行,確保中斷訊號正確傳送到正在執行的步驟。
當啟動優雅停機時,作業執行將停止當前活動的步驟,並使用一致的狀態更新作業倉庫,從而實現可重啟性。一旦正在執行的步驟完成,作業執行將被標記為已停止,並執行任何必要的清理操作。
Java Flight Recorder (JFR) 的可觀測性
除了現有的 Micrometer 指標外,Spring Batch 6.0 還引入了對 Java Flight Recorder (JFR) 的支援,以提供增強的可觀測性功能。
JFR 是一個強大的分析和事件收集框架,內置於 Java 虛擬機器 (JVM) 中。它允許您以最小的效能開銷捕獲有關應用程式執行時行為的詳細資訊。
此版本引入了幾個 JFR 事件,用於監控批處理作業執行的關鍵方面,包括作業和步驟執行、專案讀取和寫入以及事務邊界。
使用 JSpecify 進行空安全註解
Spring Batch 6.0 API 現在使用 JSpecify 註解進行標註,以提供更好的空安全保證並提高程式碼質量。
本地分塊支援
與遠端分塊類似,本地分塊是一項新功能,允許您在同一 JVM 中使用多個執行緒並行處理專案的塊。當您有大量專案需要處理並希望利用多核處理器時,此功能特別有用。透過本地分塊,您可以配置面向塊的步驟以使用多個執行緒併發處理專案的塊。每個執行緒將獨立讀取、處理和寫入其自己的專案塊,而步驟將管理整個執行並提交結果。
Spring Integration 訊息通道的 SEDA 風格
在 Spring Batch 5.2 中,我們使用 BlockingQueueItemReader 和 BlockingQueueItemWriter 元件引入了使用本地執行緒的 SEDA(分階段事件驅動架構)風格處理概念。在此基礎上,Spring Batch 6.0 引入了使用 Spring Integration 訊息通道進行大規模 SEDA 風格處理的支援。這允許您解耦批處理作業的不同階段,並使用訊息通道非同步處理它們。透過利用 Spring Integration,您可以輕鬆配置和管理訊息通道,並利用訊息轉換、過濾和路由等功能。
Jackson 3 支援
Spring Batch 6.0 已升級以支援 Jackson 3.x 進行 JSON 處理。此次升級確保了與 Jackson 庫中最新功能和改進的相容性,同時還提供了更好的效能和安全性。Spring Batch 中所有與 JSON 相關的元件,例如 JsonItemReader 和 JsonFileItemWriter,以及 JacksonExecutionContextStringSerializer 都已更新為預設使用 Jackson 3.x。
對 Jackson 2.x 的支援已棄用,並將在未來的版本中刪除。如果您當前在 Spring Batch 應用程式中使用 Jackson 2.x,建議升級到 Jackson 3.x 以利用最新功能和改進。
遠端步驟支援
此版本引入了對遠端步驟執行的支援,允許您在遠端機器或叢集上執行批處理作業的步驟。此功能對於大規模批處理場景特別有用,在這種場景中,您希望將工作負載分配到多個節點以提高效能和可伸縮性。遠端步驟執行透過使用 Spring Integration 訊息通道來促進,這些通道實現了本地作業執行環境和遠端步驟執行器之間的通訊。
Lambda 風格配置
此版本引入了使用上下文 lambda 表示式來配置批處理工件。這種新的配置風格提供了一種更簡潔易讀的方式來定義專案讀取器和寫入器。
例如,您不再需要像這樣使用傳統的構建器模式:
var reader = new FlatFileItemReaderBuilder()
.resource(...)
.delimited()
.delimiter(",")
.quoteCharacter('"')
...
.build();
您現在可以使用 lambda 表示式配置分隔選項,如下所示:
var reader = new FlatFileItemReaderBuilder()
.resource(...)
.delimited (config -> config.delimiter(',').quoteCharcter( '"' ))
...
.build();
廢棄和精簡
與任何主要版本一樣,Spring Batch 6.0 中也廢棄或刪除了一些功能。以下更改值得注意:
-
所有以前版本的廢棄 API 和功能均已刪除
-
透過
@EnableBatchProcessing(modular = true)進行的模組化配置已廢棄 -
此版本中廢棄了多個 API,以簡化核心 API 並縮小其範圍
-
在
spring-batch-test模組中廢棄 JUnit 4 支援 -
廢棄 Jackson 2 支援
-
廢棄透過
batch:…名稱空間的 XML 配置
有關更多詳細資訊,請參閱遷移指南。