對 Fargate 上的 Java 類別載入問題進行疑難排解 - Amazon Elastic Container Service

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

對 Fargate 上的 Java 類別載入問題進行疑難排解

在 Fargate 上執行的 Java 應用程式可能會在平台更新後遇到類別載入問題,特別是當應用程式依賴於非確定性類別載入行為時。這可能會表現為相依性注入錯誤、Spring Boot 失敗,或先前部署中不存在的其他執行時期例外狀況。

徵狀

您可能會遇到下列症狀:

  • Spring Boot 相依性注入錯誤

  • ClassNotFoundException 或 NoClassDefFoundError 例外狀況

  • 先前在 Fargate 上正常執行的應用程式現在會間歇性失敗

  • 相同的容器映像可在 Amazon EC2 上運作,但在 Fargate 上失敗

  • 相同容器映像在不同部署間行為不一致

原因

這些問題通常由下列原因所致:

  • 非確定性類別載入:當底層平台變更檔案的存取或快取方式時,依賴於從 JAR 檔案載入類別順序的 Java 應用程式可能會失敗。

  • 平台更新:Fargate 平台版本更新可能會變更底層檔案系統行為,影響探索與載入類別的順序。

  • JAR 檔案排序相依性:在未經明確相依性管理,而隱含依賴特定 JAR 載入順序的應用程式。

Resolution

若要解決 Fargate 上的 Java 類別載入問題,請實作確定性類別載入實務:

立即修正

如果您需要立即解決方法:

  1. 強制指定 JAR 載入順序:明確指定在應用程式的 classpath 組態中載入 JAR 檔案的順序。

  2. 使用明確相依性管理:確保在建置組態 (Maven、Gradle 等) 中明確宣告所有相依性,而不是依賴暫時性相依性。

長期最佳實務

實作這些實務,防止未來會出現的類別載入問題:

  1. 確保類別載入具有決定性:

    • 在建置檔案中使用明確的相依性宣告

    • 避免依賴 classpath 掃描順序

    • 使用相依性管理工具來解決版本衝突

    • 使用 Java 虛擬機器 (JVM) 選項,例如 -verbose:class 來取得 JVM 所載入類別的相關資訊。

  2. Spring Boot 應用程式:

    • @ComponentScan 搭配明確的基本套件使用

    • 明確設定 Bean 以避免自動設定衝突

    • 使用 @DependsOn 註釋來控制 Bean 初始化順序

  3. 建置組態:

    • 使用 Maven 或 Gradle 中的相依性管理區段

    • 排除造成衝突的暫時性相依性

    • 使用 Maven Enforcer 外掛程式等工具來偵測相依性問題

  4. 測試:

    • 使用不同的 JVM 實作測試應用程式

    • 執行模擬不同部署環境的整合測試

    • 使用工具分析開發期間的 classpath 衝突

預防

若要防止未來部署中出現 Java 類別載入問題:

  • 遵循決定性類別載入實務:設計應用程式,使其不依賴從 classpath 載入類別的順序。

  • 使用明確相依性管理:一律在建置組態中明確宣告所有必要的相依性及其版本。

  • 跨環境測試:定期測試不同環境與平台版本的應用程式,及早識別潛在問題。

  • 監控平台更新:隨時掌握 Fargate 平台更新,並在新平台版本影響生產工作負載之前測試應用程式。