排查 spring Boot 2 應用在 docker 容器中異常退出的問題 (Exited 139)
本文分析 spring boot 2 應用在 Docker 容器中異常停止,并提供解決方案。 問題表現為容器狀態顯示為 Exited (139),日志包含 SIGILL (0x4) 錯誤,以及指向 libawt.so 的錯誤信息。
根據提供的 Dockerfile、docker-compose 文件和日志,問題可能源于圖形驗證碼庫和基礎鏡像的依賴缺失。 應用使用了需要 Java AWT 庫的圖形驗證碼庫,而 openjdk:8-jdk-alpine 鏡像精簡,缺失 libawt_xawt.so 等 AWT 庫文件。 雖然已安裝字體庫,但仍未解決 AWT 庫缺失問題。 ldd 命令也證實了 libawt_xawt.so 缺失。 AWT 庫缺失導致圖形化操作時出現 SIGILL (非法指令) 異常,最終導致容器退出。
雖然 Exited (139) 也可能與內存不足等有關,但結合 libawt.so 錯誤信息,更可能是依賴庫缺失導致程序崩潰。 服務器內存充足,內存不足可能性較小。
建議嘗試以下方法:
-
更換基礎鏡像: 使用包含完整 AWT 支持的鏡像,例如基于 debian 或 centos 的 OpenJDK 鏡像,直接解決 AWT 庫缺失。
-
安裝圖形庫: 如果必須使用 openjdk:8-jdk-alpine,則需在 Dockerfile 中安裝 xorg-x11-utils (或等效包) 等圖形庫,提供 AWT 運行環境。 需仔細檢查 AWT 的依賴關系,確保安裝所有必要庫文件。
-
分析 hs_err_pid1.log: 該文件包含 jvm 崩潰的詳細信息,提供更準確的錯誤原因。
-
精簡或禁用圖形驗證碼: 考慮使用無需 AWT 的圖形驗證碼庫,或在生產環境中禁用圖形驗證碼功能。 這是一種權宜之計,需根據實際情況權衡。
解決問題的關鍵在于確保容器內的 Java 環境擁有完整的 AWT 支持。