常見問題

是否可以多線程或多進程執行 Job?

有三種方法可以處理這個問題 - 但我們建議在分析這些需求時要謹慎(真的有必要嗎?)。

  • 在 step 中加入 TaskExecutor。用於設定 Step 的 StepBuilder 提供了 "taskExecutor" 屬性供您設定。只要 step 本質上是可重新啟動的(實際上是等冪的),這就可以運作。平行 Job 範例展示了它在實務中如何運作 - 這使用「處理指示器」模式來標記輸入記錄為已完成,在業務交易內部。

  • 使用 PartitionStep 在數個 Step 實例之間明確地分割您的 step 執行。Spring Batch 針對此策略(PartitionHandler)有一個本地多線程實作,這使其成為 IO 密集型 Job 的絕佳選擇。記得為以這種方式執行的 step 中的有狀態元件使用 scope="step",以便為每個 step 執行建立單獨的實例,並且線程之間沒有串擾。

  • 使用 spring-batch-integration 模組中實作的遠端 Chunking 方法。這需要一些持久的中介軟體(例如 JMS),以便在驅動 step 和遠端工作者之間進行可靠的通訊。基本概念是在驅動進程上使用特殊的 ItemWriter,並在工作進程上使用監聽器模式(透過 ChunkProcessor)。

如何使 Item Reader 成為線程安全的?

您可以同步 read() 方法(例如,透過將其包裝在執行同步的委派器中)。請記住,您將失去重新啟動能力,因此最佳實務是將 step 標記為不可重新啟動,為了安全(和效率),您也可以在 reader 上設定 saveState=false

Spring Batch 在使用彈性策略和預設實作方面的哲學是什麼?您可以為這個或那個屬性新增一個 public getter 嗎?

Spring Batch 中有許多擴充點,適用於框架開發人員(相對於業務邏輯的實作者)。我們期望客戶建立他們自己更具體的策略,這些策略可以插入以控制諸如 commit 間隔(CompletionPolicy)、關於如何處理異常的規則(ExceptionHandler)以及許多其他內容。

一般來說,我們試圖勸阻用戶擴充框架類別。Java 語言沒有給我們足夠的彈性來將類別和介面標記為內部。一般來說,您可以預期 org.springframework.batch.* 套件中原始碼樹最上層的任何內容都是 public 的,但不一定是可子類化的。不鼓勵擴充我們大多數策略的具體實作,而建議採用組合或分支方法。如果您的程式碼只能使用 Spring Batch 的介面,那麼這將為您提供最大的可移植性。

Spring Batch 與 Quartz 有何不同?它們在解決方案中都有存在的空間嗎?

Spring Batch 和 Quartz 有不同的目標。Spring Batch 提供處理大量資料的功能,而 Quartz 提供排程任務的功能。因此 Quartz 可以補充 Spring Batch,但它們並非互斥的技術。一個常見的組合是使用 Quartz 作為 Spring Batch Job 的觸發器,使用 Cron 運算式和 Spring Core 便利的 SchedulerFactoryBean

如何使用 Spring Batch 排程 Job?

使用排程工具。市面上有許多排程工具。例如:Quartz、Control-M、Autosys。Quartz 沒有 Control-M 或 Autosys 的所有功能 - 它應該是輕量級的。如果您想要更輕量級的東西,您可以直接使用作業系統(cronat 等)。

簡單的循序依賴關係可以使用 Spring Batch 的 Job-Step 模型和 Spring Batch 中的非循序功能來實作。我們認為這很常見。實際上,這更容易糾正排程器的常見誤用 - 配置了數百個 Job,其中許多 Job 並非獨立的,而僅僅依賴於另一個 Job。

Spring Batch 如何讓專案最佳化效能和可擴展性(透過平行處理或其他方式)?

我們將此視為 JobStep 的角色之一。Step 的特定實作處理了分解業務邏輯並在平行進程或處理器之間有效共享業務邏輯的問題(請參閱 PartitionStep)。有許多技術可以在這裡發揮作用。本質上只是一組對分散式代理程式的並行遠端呼叫,這些代理程式可以處理一些業務處理。由於業務處理通常已經模組化 - 例如,輸入一個 item,處理它 - Spring Batch 可以策略性地以多種方式分配。我們有一些經驗的一個實作是一組處理業務處理的遠端 Web 服務。我們將輸入的主要索引鍵的特定範圍發送到多個遠端呼叫中的每一個。相同的基本策略適用於任何 Spring Remoting 協定(plain RMI、HttpInvoker、JMS、Hessian 等),只需在執行層配置中更改幾行程式碼即可。

如何使用訊息傳遞來擴展批次架構?

來自現有專案的大量實務證據表明,批次處理的管線方法非常有益,可以提高彈性和高吞吐量。我們經常面臨需要稽核追蹤至關重要的任務關鍵型應用程式,並且需要保證處理,但在負載下的效能受到極其嚴格的限制,或者高吞吐量帶來競爭優勢。

Matt Welsh 的研究表明,階段事件驅動架構 (SEDA) 比更僵化的處理架構具有巨大的優勢,而訊息導向中介軟體(JMS、AQ、MQ、Tibco 等)為我們提供了許多開箱即用的彈性。在下游和上游階段之間存在回饋的系統中,存在特殊的好處,因此可以調整消費者的數量以適應需求的數量。那麼這如何融入 Spring Batch 呢?spring-batch-integration 專案已在 Spring Integration 中實作了此模式,可用於擴展任何具有許多 item 要處理的 step 的遠端處理。特別參閱「chunk」套件,以及其中的 ItemWriterChunkHandler 實作。