Spring Boot+MySQL Docker部署遇HikariPool初始化异常求助
问题核心分析
你的HikariPool初始化失败本质是Spring Boot容器无法连接到MySQL容器,主要有几个关键原因:
- 生产环境的数据库配置未正确覆盖(仍在使用localhost:3307)
depends_on仅保证启动顺序,不等待MySQL完全就绪- MySQL环境变量配置冗余可能引发问题
- 手动引入的Hibernate版本与Spring Boot自带版本冲突
分步解决方案
1. 确保数据库配置在Docker环境中正确生效
你设置了SPRING_PROFILES_ACTIVE=prod,但当前只有默认的application.properties,且里面的URL还是localhost:3307(这是宿主机映射的端口,容器内部应该连MySQL容器的3306端口)。
两种修复方式选其一:
方式A:添加生产环境配置文件
在项目中创建application-prod.properties,内容如下:
server.port=3005 spring.application.name=user-service # 容器内部连接MySQL容器的3306端口,主机名用容器名mysqldb spring.datasource.url=jdbc:mysql://mysqldb:3306/bank_app?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update spring.jpa.generate-ddl=true
方式B:在docker-compose中直接覆盖环境变量
在user-service的environment里添加数据库配置,强制覆盖:
environment: - SPRING_PROFILES_ACTIVE=prod - SPRING_APPLICATION_NAME=user-service - SPRING_DATASOURCE_URL=jdbc:mysql://mysqldb:3306/bank_app?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC - SPRING_DATASOURCE_USERNAME=root - SPRING_DATASOURCE_PASSWORD=123456 - SPRING_APPLICATION_JSON={"eureka":{"client":{"serviceUrl":{"defaultZone":"http://eureka-service:8761/eureka"}}}}
2. 让Spring Boot等待MySQL完全就绪
depends_on: - mysqldb只是让user-service在mysqldb之后启动,但MySQL容器启动后还需要几秒初始化时间,此时Spring Boot尝试连接会失败。
修改docker-compose.yml,给mysqldb添加健康检查,并让user-service等待MySQL健康:
services: mysqldb: image: mysql:latest container_name: mysqldb restart: unless-stopped # 去掉重复的MYSQL_USER=root,root是默认超级用户,无需创建 environment: - MYSQL_ROOT_PASSWORD=123456 - MYSQL_DATABASE=bank_app ports: - 3307:3306 volumes: - db:/var/lib/mysql networks: - main-network # 添加健康检查 healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p123456"] interval: 5s timeout: 5s retries: 5 user-service: build: context: ../code/user-service dockerfile: Dockerfile image: user-service container_name: user-service restart: on-failure # 修改depends_on为等待健康状态 depends_on: mysqldb: condition: service_healthy ports: - 3005:3005 environment: # ... 保留原有环境变量,添加数据库配置或用方式A的prod文件 networks: - main-network
3. 修复Hibernate依赖冲突
Spring Boot 3.0.1已经集成了Hibernate 6.1.6.Final,你手动引入的hibernate-core 6.1.7.Final会导致版本冲突,直接删除pom.xml中的这段依赖:
<dependency> <groupId>org.hibernate.orm</groupId> <artifactId>hibernate-core</artifactId> <version>6.1.7.Final</version> <type>pom</type> </dependency>
改用Spring Boot的JPA starter即可(如果没加的话):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
4. 验证网络连通性(可选排查步骤)
如果以上步骤仍未解决,进入user-service容器测试MySQL连通性:
# 进入user-service容器 docker exec -it user-service bash # 安装ping工具(如果容器是alpine镜像) apk add iputils # ping mysqldb,看是否能解析 ping mysqldb # 用telnet测试端口 telnet mysqldb 3306
如果ping不通,检查是否在同一个main-network网络中;如果telnet不通,检查MySQL容器的3306端口是否正常监听。
内容的提问来源于stack exchange,提问作者user21213468

