使用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 Retry依赖,实现更完善的连接重试逻辑。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 - 容器端等待服务就绪:在项目根目录放入
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
相关产品推荐
相关产品推荐

