排查 spring boot 2 應用在 docker 中異常停止的問題
本文分析 spring boot 2 應用在 docker 容器中異常停止,并返回 Exited(139) 狀態碼,日志顯示 SIGILL (0x4) 和 libawt.so 相關錯誤的原因及解決方法。
問題癥狀:容器退出碼為 Exited(139),日志包含 SIGILL (0x4) at pc=0x00007f78d6c50816 和 Problematic frame: C [libawt.so+0x2d816] 等信息。
問題根源分析:該問題可能與使用 HutTool 圖形驗證碼和基礎鏡像選擇有關。使用 openjdk:8-jdk-alpine 作為基礎鏡像,雖然添加了字體庫 ttf-dejavu 和 fontconfig,但該精簡鏡像缺少完整的圖形化環境,特別是 AWT (Abstract Window Toolkit) 相關的庫文件,例如 libawt_xawt.so。 libawt.so 錯誤和 libjawt.so 加載失敗正是由于缺少這些依賴導致的。
解決方法:
-
更換基礎鏡像: 避免使用精簡的 openjdk:8-jdk-alpine 鏡像。選擇包含完整 Java 環境和 AWT 依賴的鏡像,例如一個基于 debian 或 centos 的鏡像。這將直接解決依賴缺失問題。
-
(不推薦) 在 Dockerfile 中安裝依賴: 如果必須使用 openjdk:8-jdk-alpine,則需要在 Dockerfile 中添加安裝 xorg-x11-utils 或其他必要 AWT 依賴的指令。但這會使鏡像體積增大,并且可能需要仔細調整 Dockerfile 的構建過程,確保依賴正確安裝和鏈接。此方法復雜且容易出錯,不推薦。
其他考慮因素:
- 內存充足: 日志中提到服務器內存充足 (32G),因此內存不足并非問題根源。
- 多個容器: 使用兩個 docker-compose 文件啟動兩個相同的應用,這本身并非問題,除非存在資源競爭。
- hs_err_pid1.log: 提供完整的 hs_err_pid1.log 文件將有助于更精確地定位問題。
總結:更換基礎鏡像是解決此問題的最有效和推薦的方法。 避免在精簡鏡像中添加大量圖形化依賴,這會增加復雜性和維護難度。 選擇合適的鏡像可以確保應用在 Docker 中穩定運行。