容器化Spring Boot应用启动失败,请求排查指导
Docker部署Spring Boot+MySQL:Spring Boot容器启动失败排查
问题描述
MySQL容器运行正常,但Spring Boot容器启动到数据库连接阶段后退出,核心报错为Public Key Retrieval is not allowed。
相关配置
application.properties
spring.datasource.url=jdbc:mysql://DB_containerfile:3306/phase2?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC spring.datasource.username=testuser spring.datasource.password= testuser@123 spring.jpa.hibernate.ddl-auto=update spring.datasource.driver-class-name= com.mysql.cj.jdbc.Driver
Dockerfile
FROM openjdk:17 ADD target/springboot-crud-api-0.0.1-SNAPSHOT.jar app.jar ENTRYPOINT ["java","-jar","app.jar"]
docker-compose.yml
version: '3.8' services: DB_containerfile: image: mysql:latest container_name: DB_containerfile environment: - MYSQL_ROOT_PASSWORD=//////////// - MYSQL_DATABASE=phase2 - MYSQL_USER=testuser - MYSQL_PASSWORD=testuser@123 backend_containerfile: image: backend_image container_name: backend_containerfile ports: - 8080:8080 build: context: ./ dockerfile: Dockerfile depends_on: - DB_containerfile
注:MYSQL_ROOT_PASSWORD为本地MySQL root用户登录密码。
错误日志
backend_containerfile | 2022-12-02 06:02:54.757 WARN 1 --- [ main] com.zaxxer.hikari.util.DriverDataSource : Registered driver with driverClassName=com.mysql.jdbc.Driver was not found, trying direct instantiation. backend_containerfile | 2022-12-02 06:02:56.040 ERROR 1 --- [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Exception during pool initialization. backend_containerfile | backend_containerfile | java.sql.SQLNonTransientConnectionException: Public Key Retrieval is not allowed backend_containerfile | at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:110) ~[mysql-connector-j-8.0.31.jar!/:8.0.31] backend_containerfile | at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-j-8.0.31.jar!/:8.0.31] backend_containerfile | at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:828) ~[mysql-connector-j-8.0.31.jar!/:8.0.31] backend_containerfile | at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:448) ~[mysql-connector-j-8.0.31.jar!/:8.0.31] backend_containerfile | at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) ~[mysql-connector-j-8.0.31.jar!/:8.0.31] backend_containerfile | at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198) ~[mysql-connector-j-8.0.31.jar!/:8.0.31] backend_containerfile | at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) ~[HikariCP-4.0.3.jar!/:na] backend_containerfile | at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364) ~[HikariCP-4.0.3.jar!/:na] backend_containerfile | at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206) ~[HikariCP-4.0.3.jar!/:na] backend_containerfile | at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476) ~[HikariCP-4.0.3.jar!/:na] backend_containerfile | at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) ~[HikariCP-4.0.3.jar!/:na] backend_containerfile | at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115) ~[HikariCP-4.0.3.jar!/:na] backend_containerfile | at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) ~[HikariCP-4.0.3.jar!/:na] backend_containerfile | at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[hibernate-core-5.6.12.Final.jar!/:5.6.12.Final]
已尝试的解决方法
- 执行
docker volume prune命令清理卷 - 移除MYSQL_USER、MYSQL_PASSWORD及Spring Boot配置中的对应账号密码,仅保留MYSQL_ROOT_PASSWORD
- 切换
spring.datasource.driver-class-name为com.mysql.cj.jdbc.Driver和com.mysql.jdbc.Driver两种配置 - 在
spring.datasource.url中添加allowPublicKeyRetrieval=true参数
排查解决方案
1. 修复密码配置的空格问题
application.properties中spring.datasource.password= testuser@123存在前置空格,导致实际密码为 testuser@123(带空格),与docker-compose中配置的testuser@123不匹配。修改为:
spring.datasource.password=testuser@123
2. 确保MySQL服务就绪后再启动后端
depends_on仅保证容器启动顺序,不保证MySQL服务完全就绪。给MySQL添加健康检查,并让后端等待MySQL健康状态:
修改docker-compose.yml的MySQL服务部分:
DB_containerfile: image: mysql:latest container_name: DB_containerfile environment: - MYSQL_ROOT_PASSWORD=//////////// - MYSQL_DATABASE=phase2 - MYSQL_USER=testuser - MYSQL_PASSWORD=testuser@123 healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "testuser", "-ptestuser@123"] interval: 10s timeout: 5s retries: 5
后端服务添加健康依赖:
backend_containerfile: # 其他配置不变 depends_on: DB_containerfile: condition: service_healthy
3. 修正驱动类配置
日志中警告找不到com.mysql.jdbc.Driver,需确保驱动类配置无空格,且依赖匹配:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
同时确认pom.xml中使用正确的MySQL Connector/J依赖:
<dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>8.0.31</version> </dependency>
4. 验证数据库用户权限
进入MySQL容器,检查testuser是否拥有phase2数据库的访问权限:
docker exec -it DB_containerfile mysql -u root -p # 输入root密码后执行 GRANT ALL PRIVILEGES ON phase2.* TO 'testuser'@'%'; FLUSH PRIVILEGES;
5. 测试容器间网络连通性
在Spring Boot容器中测试与MySQL容器的网络连通性:
# 测试ping连通 docker exec -it backend_containerfile ping DB_containerfile # 测试3306端口是否开放 docker exec -it backend_containerfile telnet DB_containerfile 3306
内容的提问来源于stack exchange,提问作者Eya_4
相关产品推荐
相关产品推荐

