Docker启动Spring Boot应用出现Segmentation Fault(错误码139)求助
问题:Spring Boot应用Docker启动时出现Segmentation Fault(错误码139)
问题场景
我有一个名为users的Spring Boot应用,通过Docker Compose启动时,应用容器直接报Segmentation fault并以错误码139退出,相关日志及配置文件如下:
启动日志
Starting docker compose Container users-user-db-1 Creating Container users-solace-1 Creating Container users-solace-1 Created Container users-user-db-1 Created Container users-users-1 Creating Container users-users-1 Created Attaching to users-users-1, users-solace-1, users-user-db-1 users-user-db-1 | The files belonging to this database system will be owned by user "postgres". users-user-db-1 | This user must also own the server process. users-user-db-1 | users-user-db-1 | The database cluster will be initialized with locale "en_US.utf8". users-user-db-1 | The default database encoding has accordingly been set to "UTF8". users-user-db-1 | The default text search configuration will be set to "english". users-user-db-1 | users-user-db-1 | Data page checksums are disabled. users-user-db-1 | users-user-db-1 | fixing permissions on existing directory /var/lib/postgresql/data ... ok users-user-db-1 | creating subdirectories ... ok users-user-db-1 | selecting dynamic shared memory implementation ... posix users-user-db-1 | selecting default max_connections ... 100 users-solace-1 | Host Boot ID: users-solace-1 | Starting VMR Docker Container: Wed Apr 5 08:21:32 UTC 2023 users-solace-1 | Setting umask to 077 users-solace-1 | SolOS Version: soltr_9.9.0.34 users-user-db-1 | selecting default shared_buffers ... 128MB users-user-db-1 | selecting default time zone ... Etc/UTC users-user-db-1 | creating configuration files ... ok users-user-db-1 | running bootstrap script ... ok users-users-1 | Segmentation fault users-users-1 exited with code 0
相关配置文件
docker-compose.sh
#!/bin/bash docker container rm -f $(docker container ls -aq) mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true docker build --no-cache -f Dockerfile.local -t users:latest . docker-compose -f docker-compose.yml up --build
Dockerfile.local
FROM <url>/openjdk:11-jdk MAINTAINER users ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} app.jar CMD java -jar /app.jar EXPOSE 8080
docker-compose.yml
version: '3' services: users: image: users:latest restart: on-failure networks: default: aliases: - users.svc links: - user-db - solace ports: - "8094:8080" depends_on: - user-db - solace environment: WAIT_HOSTS: solace.svc:8080, user-db.svc:5432 USERS_DB_JDBC_URL: jdbc:postgresql://user-db.svc:5432/users USERS_DB_APP_USER_NAME: USERS_rwuser USERS_DB_APP_USER_PASSWORD: mysecretpassword USERS_DB_MIGRATION_USER_NAME: USERS_rwuser USERS_DB_MIGRATION_USER_PASSWORD: mysecretpassword USERS_DB_READ_WRITE_USER_ROLE: USERS_rwuser USERS_DB_READ_ONLY_USER_ROLE: USERS_rwuser SOLACE_HOST_URL: tcp://solace.svc:55555 SOLACE_MSG_VPN: default USERS_SOLACE_USERNAME: admin USERS_SOLACE_PASSWORD: admin command: > java -jar /app.jar" user-db: image: <URL>/postgres:12.4 restart: always networks: default: aliases: - user-db.svc ports: - 5432:5432 environment: POSTGRES_USER: USERS_rwuser POSTGRES_PASSWORD: mysecretpassword POSTGRES_DB: users solace: image: <URL>/solace/solace-pubsub-standard:9.9.0.34 restart: always networks: default: aliases: - solace.svc shm_size: 1g ulimits: core: 1 nofile: soft: 2448 hard: 38048 environment: - system_scaling_maxconnectioncount=100
解决方案
1. 修复docker-compose.yml中的语法错误
查看users服务的command配置,末尾存在多余的双引号,会导致命令解析异常:
command: > java -jar /app.jar"
修正方式:去掉多余引号,或者直接删除整个command字段(Dockerfile中已定义CMD,重复定义可能引发冲突):
# 修正后的command配置 command: > java -jar /app.jar
2. 更换可靠的JDK基础镜像
当前使用的<url>/openjdk:11-jdk可能存在兼容性问题,建议替换为官方维护的镜像:
# 官方OpenJDK轻量镜像 FROM openjdk:11-jdk-slim # 或使用Adoptium维护的镜像 FROM eclipse-temurin:11-jdk
3. 确保依赖服务完全就绪
depends_on仅保证容器启动,不保证服务内部就绪。当前WAIT_HOSTS配置的Solace端口是8080(管理端口),但应用实际连接的是55555业务端口,建议调整:
WAIT_HOSTS: solace.svc:55555, user-db.svc:5432
也可使用wait-for-it脚本替代原生等待逻辑,确保PostgreSQL和Solace服务完全启动后再启动Spring Boot应用。
4. 调整JVM内存参数
Segmentation Fault可能与内存分配异常有关,在启动命令中添加JVM内存限制参数:
command: > java -Xmx512m -Xms256m -jar /app.jar
可根据应用实际需求调整-Xmx(最大堆内存)和-Xms(初始堆内存)的值。
5. 启用核心转储排查深层问题
在users服务中添加ulimits配置开启核心转储,方便定位崩溃点:
users: # 其他配置... ulimits: core: unlimited
启动后若再次崩溃,可进入容器使用gdb分析核心文件:
# 进入容器 docker exec -it users-users-1 bash # 分析核心文件 gdb java core.<PID>
内容的提问来源于stack exchange,提问作者user2800089
相关产品推荐
相关产品推荐

