Spring Batch中管理長時間執行作業:解決連線問題

banq發表於2024-05-17


在 Spring Batch 中處理長時間執行的作業可能很棘手,尤其是在管理資料庫連線和事務時。在我們關於 Developer's Coffee 的最新文章中,我們深入探討了 Spring Batch 作業由於連線限制而超時的現實問題。

瞭解我們如何透過調整 HikariCP 設定和調整負載平衡器超時來解決該問題,以確保批處理順利可靠。請繼續閱讀,詳細瞭解我們的解決方案以及如何將它們應用到您的專案中。

Spring Batch 是一個用於處理大量資料的強大框架。然而,在處理長時間執行的作業時,尤其是在資料庫連線和事務管理方面,它可能會帶來挑戰。在這篇文章中,我們將探討在長時間執行的批處理作業中遇到的實際問題以及我們如何解決它。

問題
我們有一個 Spring Batch 作業,其中包括多個步驟,其中一個步驟需要花費相當多的時間來執行。該作業使用 HikariCP 進行連線池,最大生命週期設定為 30 分鐘。使用的資料庫是 YugabyteDB。

這是我們的作業配置的片段:

return new StepBuilder(<font>"step1", jobRepository)
        .<UUID, UUID>chunk(employeeTmpProcessorPageSize, transactionManager)
        .reader(employeeTmpReader)
        .writer(employeeTmpWriter)
        .faultTolerant()
        .skipLimit(step1SkipLimit)
        .skip(RuntimeException.class)
        .allowStartIfComplete(true)
        .listener(new SPItemProcessorListener())
        .taskExecutor(taskExecutor)
        .build();

在執行過程中,如果step1花費的時間超過30分鐘,我們會遇到以下異常:

org.springframework.dao.DataAccessResourceFailureException: PreparedStatementCallback; SQL [UPDATE ...]; An I/O error occurred while sending to the backend.; nested exception is com.yugabyte.util.PSQLException: An I/O error occurred while sending to the backend.
...
Caused by: java.sql.SQLException: Connection is closed
    at com.zaxxer.hikari.pool.ProxyConnection$ClosedConnection.lambda$getClosedConnection$0(ProxyConnection.java:502)

根本原因分析 (RCA)
1.連線超時:HikariCP 連線池關閉空閒時間超過 30 分鐘的連線。這會導致超出此持續時間的長時間執行步驟出現問題。

2.資料庫負載均衡器超時:負載均衡器的空閒超時設定為較低值(例如,30 分鐘),導致長時間執行的事務的連線丟失。

3.事務上下文:Spring Batch 的事務上下文維護連線以更新作業後設資料。當連線關閉時,會導致更新此後設資料失敗。
解決方案

為了解決這個問題,我們實施了以下更改:
1.增加 HikariCP max-lifetime:此設定增加到更高的值,以確保連線在長時間執行的步驟期間保持開啟狀態。然而,這只是一個臨時措施。
spring.datasource.hikari.max-lifetime=5400000 # 90 minutes

2.調整負載均衡器超時:我們將 Azure 負載均衡器上的空閒超時設定增加到 60 分鐘,以與我們預期的作業執行時間保持一致。

3.定期連線驗證:我們新增了連線驗證查詢,以在長時間執行的步驟期間定期檢查和重新整理連線。

spring.datasource.hikari.validation-timeout=30000 # 30 seconds
spring.datasource.hikari.idle-timeout=60000 # 60 seconds

結果
實施這些更改後,長時間執行的批處理作業成功執行,沒有連線超時問題。作業儲存庫能夠維護和更新作業執行上下文,確保資料一致性和作業成功完成。

結論
在 Spring Batch 中處理長時間執行的作業需要仔細考慮資料庫連線設定和事務管理。透過延長連線壽命並使負載均衡器設定與作業要求保持一致,我們可以確保穩健可靠的批處理。
 

相關文章