常見問題
是否可以在多執行緒或多程序中執行作業?
有三種方法可以解決這個問題 - 但我們建議在分析此類需求時謹慎行事(這真的有必要嗎?)。
-
向 step 新增 TaskExecutor。用於配置 Steps 的 `StepBuilder` 提供了可以設定的 "taskExecutor" 屬性。只要 step 本身是可重啟的(實際上是冪等的),這種方法就有效。並行作業示例展示了它在實踐中如何工作 - 這使用了一種“處理指示器”模式,在業務事務內部將輸入記錄標記為完成。
-
使用
PartitionStep
將您的 step 執行明確地分配給多個 Step 例項。Spring Batch 對此主要策略 (PartitionHandler
) 有一個本地多執行緒實現,這使得它成為 IO 密集型作業的絕佳選擇。請記住,對於以這種方式執行的 step 中的有狀態元件,使用scope="step"
,以便為每個 step 執行建立單獨的例項,並且執行緒之間沒有交叉通訊。 -
使用
spring-batch-integration
模組中實現的遠端分塊 (Remote Chunking) 方法。這需要一些持久化的中介軟體(例如 JMS)來實現驅動 step 和遠端工作執行緒之間的可靠通訊。基本思想是在驅動程序上使用特殊的ItemWriter
,並在工作程序上(透過ChunkProcessor
)使用監聽器模式。
如何使 item reader 執行緒安全?
您可以同步 read()
方法(例如,透過將其包裝在一個執行同步的委託器中)。請記住,您會失去可重啟性,因此最佳實踐是將 step 標記為不可重啟,並且為了安全(和高效),您還可以將讀取器上的 saveState=false
設定為 false。
Spring Batch 關於使用靈活策略和預設實現的理念是什麼?是否可以為此或彼屬性新增公共 getter?
Spring Batch 為框架開發人員(與業務邏輯實現者相對)提供了許多擴充套件點。我們期望客戶端建立自己的更具體的策略,這些策略可以插入進來控制諸如提交間隔 (CompletionPolicy
)、處理異常的規則 (ExceptionHandler
) 等等。
通常,我們試圖勸阻使用者不要擴充套件框架類。Java 語言在將類和介面標記為內部方面沒有給我們太多靈活性。通常,您可以預期原始碼樹頂層包 org.springframework.batch.*
中的任何內容都是公共的,但不一定可以被子類化。不鼓勵擴充套件我們大多數策略的具體實現,而傾向於組合或分支方法。如果您的程式碼只能使用 Spring Batch 的介面,那將為您提供最大的可移植性。
Spring Batch 與 Quartz 有何不同?它們是否可以在同一個解決方案中共存?
Spring Batch 和 Quartz 有不同的目標。Spring Batch 提供處理大量資料的功能,而 Quartz 提供排程任務的功能。因此,Quartz 可以補充 Spring Batch,但不是互斥的技術。常見的組合是使用 Quartz 作為 Spring Batch 作業的觸發器,使用 Cron 表示式和 Spring Core 提供的便利 SchedulerFactoryBean
。
如何使用 Spring Batch 排程作業?
使用排程工具。有很多可用的工具。例如:Quartz, Control-M, Autosys。Quartz 不具備 Control-M 或 Autosys 的所有功能 - 它應該是一個輕量級的工具。如果您想要更輕量級的工具,可以直接使用作業系統(cron
, at
等)。
簡單的順序依賴關係可以使用 Spring Batch 的 job-steps 模型和 Spring Batch 中的非順序特性來實現。我們認為這很常見。事實上,這使得更容易糾正排程器的一種常見誤用 - 配置數百個作業,其中許多不是獨立的,而只依賴於另一個作業。
Spring Batch 如何透過並行處理或其他方式最佳化專案效能和可擴充套件性?
我們認為這是 Job
或 Step
的作用之一。Step 的特定實現處理拆分業務邏輯並有效地在並行程序或處理器之間共享的問題(參見 PartitionStep
)。有許多技術可以在這裡發揮作用。其本質就是對分散式代理進行一組併發遠端呼叫,這些代理可以處理一些業務處理。由於業務處理通常已經模組化了 - 例如,輸入一個 item,處理它 - Spring Batch 可以透過多種方式策略性地分配。我們有過經驗的一種實現是一組處理業務處理的遠端 Web 服務。我們將輸入的主鍵範圍傳送給許多遠端呼叫中的每一個。相同的基本策略適用於任何 Spring Remoting 協議(純 RMI, HttpInvoker, JMS, Hessian 等),只需修改執行層配置中的幾行程式碼即可。
如何使用訊息傳遞來擴充套件批處理架構?
現有專案有大量實踐證據表明,批處理採用管道方法非常有益,可以提高彈性和高吞吐量。我們經常面臨任務關鍵型應用,其中審計日誌至關重要,並要求保證處理,但在負載下的效能有非常嚴格的限制,或者高吞吐量能帶來競爭優勢。
Matt Welsh 的工作表明,分階段事件驅動架構 (Staged Event Driven Architecture, SEDA) 比更僵化的處理架構具有巨大的優勢,並且面向訊息的中介軟體(JMS, AQ, MQ, Tibco 等)為我們提供了開箱即用的強大彈性。在下游和上游階段之間存在反饋的系統中尤其有益,因此可以調整消費者數量以應對需求量。那麼這如何融入 Spring Batch 呢?spring-batch-integration 專案在 Spring Integration 中實現了這種模式,可用於擴充套件處理大量資料項的任何 step 的遠端處理能力。特別參見“chunk”包以及其中的 ItemWriter
和 ChunkHandler
實現。