You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Docker-Compose连接SpringBoot与MySQL容器时出现通信链路故障

SpringBoot容器连接MySQL容器失败,循环重启重试问题

执行docker-compose up后,SpringBoot应用启动后反复尝试连接MySQL容器,报错com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failures,进入重启循环。

相关配置文件

docker-compose.yml

version: '3.8'

services:
  mysqldb:
    image: mysql
    platform: linux/x86_64
    env_file: ./.env
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=$MYSQLDB_ROOT_PASSWORD
      - MYSQL_DATABASE=$MYSQLDB_DATABASE
    ports:
      - $MYSQLDB_LOCAL_PORT:$MYSQLDB_DOCKER_PORT
    volumes:
      - db:/var/lib/mysql
  app:
    depends_on:
     - mysqldb
    build: .
    restart: always
    env_file: ./.env
    ports:
      - $APP_LOCAL_PORT:$APP_DOCKER_PORT
    environment:
      - DB_HOST=mysqldb
      - DB_USER=$MYSQLDB_USER
      - DB_PASSWORD=$MYSQLDB_ROOT_PASSWORD
      - DB_NAME=$MYSQLDB_DATABASE
      - DB_PORT=$MYSQLDB_DOCKER_PORT
    stdin_open: true
    tty: true

volumes: 
  db:

.env

MYSQLDB_USER=root
MYSQLDB_ROOT_PASSWORD=12345678
MYSQLDB_DATABASE=dronefeederdb
MYSQLDB_LOCAL_PORT=3306
MYSQLDB_DOCKER_PORT=3306

APP_LOCAL_PORT=8080
APP_DOCKER_PORT=8080

application.yaml

server:
  port: 8080
spring:
    datasource:
        username: ${DB_USER}
        password: ${DB_PASSWORD}
        url: jdbc:mysql://${DB_HOST}:${DB_PORT}/${DB_NAME}
    jpa:
        hibernate:
            ddl-auto: update
        show-sql: true
        open-in-view: false
    security.user:
        name: dronefeeder
        password: dronefeeder

resilience4j.circuitbreaker:
  configs:
    default:
      waitDurationInOpenState: 10s
      failureRateThreshold: 10

Dockerfile

FROM openjdk:11.0-jdk as build-image
WORKDIR /app
COPY . .
RUN ./mvnw clean package -DskipTests

FROM openjdk:11.0-jre
COPY --from=build-image /app/target/*.jar /app/app.jar
EXPOSE 8080
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom", "-jar", "/app/app.jar"]

解决方法

1. 处理MySQL服务就绪延迟问题

depends_on仅保证容器启动顺序,不代表MySQL服务已经完全就绪(初始化数据库、启动服务需要时间),可以通过两种方式解决:

  • SpringBoot端配置连接重试:修改application.yaml,补充JDBC URL参数和连接池重试配置:
    spring:
      datasource:
        username: ${DB_USER}
        password: ${DB_PASSWORD}
        url: jdbc:mysql://${DB_HOST}:${DB_PORT}/${DB_NAME}?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
        hikari:
          connection-timeout: 30000
          maximum-pool-size: 10
          minimum-idle: 2
          connection-test-query: SELECT 1
    
    也可以添加Spring Retry依赖,实现更完善的连接重试逻辑。
  • 容器端等待服务就绪:在项目根目录放入wait-for-it.sh脚本,修改Dockerfile和docker-compose.yml,让应用等待MySQL服务就绪后再启动:
    FROM openjdk:11.0-jdk as build-image
    WORKDIR /app
    COPY . .
    RUN ./mvnw clean package -DskipTests
    
    FROM openjdk:11.0-jre
    COPY --from=build-image /app/target/*.jar /app/app.jar
    COPY wait-for-it.sh /app/wait-for-it.sh
    RUN chmod +x /app/wait-for-it.sh
    EXPOSE 8080
    ENTRYPOINT ["/app/wait-for-it.sh", "mysqldb:3306", "--", "java","-Djava.security.egd=file:/dev/./urandom", "-jar", "/app/app.jar"]
    

2. 匹配MySQL版本与JDBC驱动兼容性

当前mysql镜像默认是最新版本,可能和Java 11的JDBC驱动不兼容,指定MySQL 8.0版本:

mysqldb:
  image: mysql:8.0
  # 其余配置不变

3. 确认环境变量传递

检查.env中变量是否正确传递,比如DB_PORT使用容器内部端口3306是正确的,容器间通信无需使用映射的本地端口。

内容的提问来源于stack exchange,提问作者Jossany Moura

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 00:01:06