AllMiniLmL6V2EmbeddingModel這類進程內模型,靠 DJL + ONNX Runtime 加載原生庫在 JVM 裡跑推理。容器裡直接 SIGSEGV 崩掉,不是 Java 例外,是 native 層執行掛了。先升 JDK 17、換 temurin 鏡像,再查原生庫依賴鏈。
Issue & Env(案發現場與環境)
- 環境:Spring Boot 2.2.5 + langchain4j + PostgreSQL pgvector。
- 現象:本地 IDEA 裡
AllMiniLmL6V2EmbeddingModel跑得好好的,放進openjdk:8基礎鏡像的容器就崩,JVM 直接退出。問題來自 langchain4j issue #1655。
StackTrace(堆疊日誌)
issue #1655 原文:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007fdb638dd4fd, pid=6, tid=0x00007fdad21ae700
#
# JRE version: OpenJDK Runtime Environment (8.0_342-b07) (build 1.8.0_342-b07)
# Java VM: OpenJDK 64-Bit Server VM (25.342-b07 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C [libc.so.6+0x15b4fd]
#
# Core dump written. Default location: //core or core.6
#
# An error report file with more information is saved as:
# //hs_err_pid6.log
關鍵兩行:SIGSEGV (0xb) 和 Problematic frame: C [libc.so.6+0x15b4fd]。崩在 native 棧上,業務程式碼的 try/catch 攔不住。
Reproduce(復現程式碼)
復現要點:進程內 embedding 模型 + openjdk:8 基礎鏡像。
FROM openjdk:8
COPY app.jar /app.jar
CMD ["java", "-jar", "/app.jar"]
啟動後用 AllMiniLmL6V2EmbeddingModel 生成向量,JVM 直接崩,留下 hs_err_pid*.log。
Root Cause(根因分析)
AllMiniLmL6V2EmbeddingModel這類進程內模型,靠 DJL + ONNX Runtime 在 JVM 內跑推理,必須加載隨平臺分發的原生庫(.so/.dll)。這條路不經過 Java 的例外體系:原生庫加載或執行失敗時,會直接把進程打掛,報的是hs_err_pid*.log,不是Exception。Problematic frame: C [libc.so.6+...]說明崩在 native 棧,業務程式碼攔不住。相關機制可參考 DJL ONNX Runtime engine 文檔。- 觸發條件有兩層。一是運行環境過老:這裡是 Java 8,而 LangChain4j 1.x 的基線是 JDK 17,見 Getting Started。二是容器裡原生庫的加載與依賴鏈不完整。
- DJL 官方文檔提到,onnxruntime 1.21+ 在部分 JDK 發行版上有衝突,會報
UnsatisfiedLinkError。實測 temurin17 與 zulu17 可用。 - 關鍵區別:日誌或構建期報
UnsatisfiedLinkError,是「原生庫沒找到」;SIGSEGV是「找到了但執行時崩了」。後者更難查。
The Fix(解決方案)
先把 JDK 升到 17+,基礎鏡像換成 eclipse-temurin:17-jre:
FROM eclipse-temurin:17-jre
COPY app.jar /app.jar
CMD ["java", "-jar", "/app.jar"]
這一條同時解決「基線不符」和「老 JDK 在容器裡的原生庫兼容性差」。
- JDK 發行版優先選 temurin 或 zulu。換髮行版後 SIGSEGV 變成
UnsatisfiedLinkError,說明前進了一步,原生庫至少可見了。繼續查架構(x86_64 還是 arm64)與 glibc 依賴。 - 排查路徑:找到
hs_err_pid*.log,看Problematic frame與Dynamic libraries段。確認基礎鏡像的 libc 與 onnxruntime 預期是否匹配。centos7 這類老 glibc 鏡像常見GLIBCXX_x.x.x not found。 - 代價更小的替代:容器裡不用進程內模型,改用遠程 embedding API,或把 embedding 拆成獨立服務,別把 native 依賴塞進業務鏡像。
- 關聯提示:SEGV 出現在 Java 8 上,本質上和「LangChain4j 1.x 需要 JDK 17」是同一類環境問題,只是表現不同。
小結
- SIGSEGV 是 native 層崩潰,不走 Java 例外體系,
hs_err_pid*.log才是第一現場。 - 先升 JDK 17、換
eclipse-temurin:17-jre,再查原生庫依賴鏈。 UnsatisfiedLinkError是庫沒找到,SIGSEGV是執行時崩,後者更難查。
References(參考來源)
- Application crashes on using AllMiniLmL6V2EmbeddingModel in docker with openjdk:8 — langchain4j issue #1655github-issue
- In-process embedding models — LangChain4j 官方文檔langchain4j-docs
- ONNX Runtime engine — DJL 官方文檔official-docs
- Getting Started(JDK 基線)— LangChain4j 官方文檔langchain4j-docs
