JVM 檢查點還原
Spring Framework 與 Project CRaC 實作的檢查點/還原整合,以便允許實作能夠減少基於 Spring 的 Java 應用程式與 JVM 的啟動和預熱時間的系統。
使用此功能需要
-
已啟用檢查點/還原的 JVM(目前僅限 Linux)。
-
類路徑中存在
org.crac:crac
程式庫(支援1.4.0
及以上版本)。 -
指定必要的
java
命令列參數,例如-XX:CRaCCheckpointTo=PATH
或-XX:CRaCRestoreFrom=PATH
。
在請求檢查點時,由 -XX:CRaCCheckpointTo=PATH 指定的路徑中產生的檔案包含執行中 JVM 記憶體的表示,其中可能包含機密和其他敏感資料。使用此功能時,應假設 JVM「看到」的任何值(例如來自環境的組態屬性)都將儲存在這些 CRaC 檔案中。因此,應仔細評估這些檔案的產生、儲存和存取位置以及方式的安全性影響。 |
從概念上講,檢查點和還原與個別 Bean 的 Spring Lifecycle
合約一致。
執行中應用程式的隨需檢查點/還原
可以隨需建立檢查點,例如使用類似 jcmd application.jar JDK.checkpoint
的命令。在建立檢查點之前,Spring 會停止所有正在執行的 Bean,讓它們有機會透過實作 Lifecycle.stop
在需要時關閉資源。還原後,相同的 Bean 會重新啟動,Lifecycle.start
允許 Bean 在相關時重新開啟資源。對於不依賴 Spring 的程式庫,可以透過實作 org.crac.Resource
並註冊相關實例來提供自訂檢查點/還原整合。
利用執行中應用程式的檢查點/還原通常需要額外的生命週期管理,以優雅地停止和啟動使用檔案或 Socket 等資源,並停止活動執行緒。 |
請注意,當以固定速率定義排程任務時,例如使用類似 @Scheduled(fixedRate = 5000) 的註解,在隨需檢查點/還原的情況下,當 JVM 還原時,將執行檢查點和還原之間所有錯過的執行。如果這不是您想要的行為,建議以固定延遲排程任務(例如使用 @Scheduled(fixedDelay = 5000) )或使用 cron 運算式,因為這些運算式是在每次任務執行後計算的。 |
如果在預熱的 JVM 上建立檢查點,則還原的 JVM 也會同樣預熱,從而可能立即達到效能峰值。此方法通常需要存取遠端服務,因此需要一定程度的平台整合。 |
啟動時自動檢查點/還原
當設定 -Dspring.context.checkpoint=onRefresh
JVM 系統屬性時,會在啟動期間的 LifecycleProcessor.onRefresh
階段自動建立檢查點。在此階段完成後,所有非延遲初始化的 Singleton 都已實例化,並且已調用 InitializingBean#afterPropertiesSet
回呼;但生命週期尚未開始,且 ContextRefreshedEvent
尚未發布。
為了測試目的,也可以利用 -Dspring.context.exit=onRefresh
JVM 系統屬性,該屬性會觸發類似的行為,但它不是建立檢查點,而是在相同的生命週期階段退出您的 Spring 應用程式,而無需 Project CraC 相依性/JVM 或 Linux。這可用於檢查在 Bean 未啟動時是否需要連線到遠端服務,並可能微調組態以避免這種情況。
如上所述,尤其是在 CRaC 檔案作為可部署成品(例如容器映像)的一部分運用的情況下,請假設 JVM「看到」的任何敏感資料最終都會出現在 CRaC 檔案中,並仔細評估相關的安全性影響。 |
自動檢查點/還原是一種將應用程式的啟動「快轉」到應用程式 Context 即將啟動的階段的方式,但它不允許擁有完全預熱的 JVM。 |