springboot2 應(yīng)用部署至 docker 容器后異常停止的排查
本文針對(duì) SpringBoot2 應(yīng)用在 docker 容器中運(yùn)行時(shí)出現(xiàn)異常停止的問題進(jìn)行分析和解答。該問題主要體現(xiàn)在容器日志中顯示 Exited (139) 狀態(tài)碼,并伴隨 libawt.so 相關(guān)的錯(cuò)誤信息。
問題描述中,開發(fā)人員使用 Docker 19.03.13 版本,Docker Compose 部署兩個(gè)相同的 SpringBoot 應(yīng)用實(shí)例(pod1 和 pod2),均分配 9G 內(nèi)存。應(yīng)用使用了 hutool 圖形驗(yàn)證碼,并基于 openjdk:8-jdk-alpine 鏡像構(gòu)建了自定義鏡像。pod2 容器運(yùn)行一段時(shí)間后異常停止,pod1 容器則由于設(shè)置了 restart: always 而自動(dòng)重啟。
容器日志顯示 Java 運(yùn)行時(shí)環(huán)境檢測(cè)到致命錯(cuò)誤 SIGILL (0x4),并在 libawt.so 庫(kù)中出現(xiàn)問題。 ldd libjawt.so 命令的輸出表明缺少 libawt_xawt.so 庫(kù),這導(dǎo)致 libjawt.so 庫(kù)無法正確加載。
雖然系統(tǒng)內(nèi)存充足,但 libawt.so 相關(guān)的錯(cuò)誤提示強(qiáng)烈暗示問題并非內(nèi)存不足,而是缺少必要的依賴庫(kù)。 openjdk:8-jdk-alpine 鏡像是一個(gè)精簡(jiǎn)版的 Java 運(yùn)行時(shí)環(huán)境,默認(rèn)不包含 AWT(抽象窗口工具包)相關(guān)的庫(kù),而 AWT 庫(kù)是 hutool 圖形驗(yàn)證碼功能所依賴的。因此,僅僅安裝 ttf-dejavu 和 fontconfig 還不夠,因?yàn)檫@些庫(kù)只是字體相關(guān)的,而 AWT 還需要更多圖形相關(guān)的庫(kù)文件。
建議嘗試以下解決方案:
- 安裝缺失的依賴庫(kù): 在 Dockerfile 中,除了 ttf-dejavu 和 fontconfig 之外,還需要安裝 xorg-x11-utils (或者其在其他發(fā)行版中的等效包)。這將提供 AWT 運(yùn)行所需的必要環(huán)境。 請(qǐng)注意,這會(huì)顯著增加鏡像大小。
- 更換基礎(chǔ)鏡像: 考慮使用一個(gè)包含完整 AWT 支持的基礎(chǔ)鏡像,例如一個(gè)包含圖形化環(huán)境的 openjdk 鏡像,而不是 openjdk:8-jdk-alpine。 這能避免復(fù)雜的依賴安裝過程,并使鏡像更加輕量級(jí)。
- 檢查 hs_err_pid1.log: 提供完整的 hs_err_pid1.log 文件,該文件包含了 Java 虛擬機(jī)崩潰的詳細(xì)堆棧信息,可以幫助更準(zhǔn)確地定位問題。
通過以上步驟,可以嘗試解決 SpringBoot 應(yīng)用在 Docker 容器中因缺少圖形化依賴而導(dǎo)致異常停止的問題。