Docker:如何延迟Spring Web应用启动至MySQL数据库就绪
解决Docker Compose中Spring应用等待MySQL服务就绪的问题
你遇到的问题是depends_on仅等待MySQL容器启动,而非服务完全就绪,导致Spring应用启动时连接失败。无需修改应用源码,有多种可行方案,并非必须使用wait-for-it.sh:
方案一:Docker Compose健康检查+条件依赖
利用Docker Compose的healthcheck特性,配置MySQL服务的健康检查规则,让Spring应用等待MySQL服务就绪后再启动。需要确保使用3.8及以上版本的Compose文件格式:
version: '3.8' services: app: build: context: . dockerfile: Dockerfile ports: - "8080:8080" depends_on: db: condition: service_healthy # 等待MySQL服务健康检查通过 environment: SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/users_db?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true SPRING_DATASOURCE_USERNAME: pp_user SPRING_DATASOURCE_PASSWORD: pp_user db: image: mysql:latest ports: - "3307:3306" environment: MYSQL_DATABASE: users_db MYSQL_USER: pp_user MYSQL_ROOT_PASSWORD: root MYSQL_PASSWORD: pp_user healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "pp_user", "-ppp_user"] interval: 5s # 每5秒执行一次健康检查 timeout: 5s # 单次检查超时时间 retries: 10 # 重试10次后判定服务不健康 start_period: 10s # 容器启动后延迟10秒再开始检查,预留初始化时间
方案二:配置Spring Boot连接池重试(仅需环境变量)
通过Spring Boot内置的Hikari连接池参数,配置连接重试逻辑,让应用自动等待MySQL服务就绪,无需修改代码:
在app服务的environment中添加以下配置:
SPRING_DATASOURCE_HIKARI_MAX_WAIT: 30000 SPRING_DATASOURCE_HIKARI_CONNECTION_TIMEOUT: 30000 SPRING_DATASOURCE_HIKARI_TEST_ON_BORROW: true SPRING_DATASOURCE_HIKARI_CONNECTION_TEST_QUERY: SELECT 1
MAX_WAIT:连接池等待可用连接的最长时间(30秒)CONNECTION_TIMEOUT:获取连接的超时时间(30秒)TEST_ON_BORROW:从连接池获取连接时测试连接有效性CONNECTION_TEST_QUERY:用于测试连接的SQL语句
方案三:自定义入口脚本延迟启动
无需修改应用镜像,直接在Docker Compose中配置entrypoint,通过脚本循环检测MySQL服务状态,就绪后再启动应用:
app: build: context: . dockerfile: Dockerfile ports: - "8080:8080" depends_on: - db entrypoint: ["/bin/sh", "-c", "until mysqladmin ping -h db -u pp_user -ppp_user; do echo 'Waiting for MySQL...'; sleep 2; done; java -jar your-app.jar"] environment: SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/users_db?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true SPRING_DATASOURCE_USERNAME: pp_user SPRING_DATASOURCE_PASSWORD: pp_user
注意:若应用容器中未安装mysqladmin,可改用nc(netcat)检测端口:
entrypoint: ["/bin/sh", "-c", "until nc -z db 3306; do echo 'Waiting for MySQL...'; sleep 2; done; java -jar your-app.jar"]
如果容器没有nc,可在Dockerfile中添加RUN apt-get update && apt-get install -y netcat(若基于Debian/Ubuntu镜像)。
内容的提问来源于stack exchange,提问作者Sergey Zolotarev
相关产品推荐
相关产品推荐

