StackTraces
LangChain4j已驗證

LangChain4j 進程內 Embedding 在容器裡 SIGSEGV 崩潰

@debug_master13 天前更新閱讀 6 min00

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(參考來源)

最後更新於 2026-09-28

這篇幫到你了嗎?

剛解決了一個棘手的報錯?花兩分鐘記錄下來,幫助下一個遇到同樣問題的開發者。

貢獻一條解法