带有Spring引导的Docker中的Mysql连接错误

Posted

技术标签:

【中文标题】带有Spring引导的Docker中的Mysql连接错误【英文标题】:Mysql Connection Error In Docker with Spring boot 【发布时间】:2020-07-24 11:05:00 【问题描述】:

我已经开始使用 docker,并且正在创建一些基本示例。当我使用 docker-copmose.yml 文件时,我遇到了 spring boot 和 mysql 连接之间的问题。

奇怪的是它在 jdbc:mysql 处出错。它正在考虑将数据库连接的第二个参数作为主机。我不知道为什么?

当我单独手动启动 mysql 和 springboot 容器时,同样的连接配置有效。我只有在使用 docker-compose 时才会遇到这个问题

application.properties

spring.datasource.username=root
spring.datasource.password=mypass
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.datasource.url=jdbc:mysql://mysql-db:3306/docker_test

Dockerfile

FROM openjdk:8u212-jre-alpine
ADD target/docker-demo-1.0.jar docker-demo-1.0.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","docker-demo-1.0.jar"]

docker-compose.yml

version: '3'
services:
    mysql-db:
        image: mysql
        container_name: mysqldbhost
        restart: always
        environment:
            MYSQL_DATABASE: docker_test
            MYSQL_ROOT_PASSWORD: mypass
        ports:
            - 3306:3306
    web-app:
        build:
            context: .
            dockerfile: Dockerfile
        image: 
            kshitij23/docker-demo:1.3
        ports:
            - "8080:8080"
        depends_on:
            - mysql-db

当我使用“docker-compose up”时出错

web-app_1   | Caused by: org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
web-app_1   |   at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:112) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final]
web-app_1   |   at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final]
web-app_1   |   at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final] 
web-app_1   |   at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final]
web-app_1   |   at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:69) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final]
web-app_1   |   at org.hibernate.tool.schema.internal.exec.ImprovedExtractionContextImpl.getJdbcConnection(ImprovedExtractionContextImpl.java:60) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final]
web-app_1   |   at org.hibernate.tool.schema.internal.exec.ImprovedExtractionContextImpl.getJdbcDatabaseMetaData(ImprovedExtractionContextImpl.java:67) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final]
web-app_1   |   at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.getTables(InformationExtractorJdbcDatabaseMetaDataImpl.java:333) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final]
web-app_1   |   at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.getTablesInformation(DatabaseInformationImpl.java:120) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final]
web-app_1   |   at org.hibernate.tool.schema.internal.GroupedSchemaMigratorImpl.performTablesMigration(GroupedSchemaMigratorImpl.java:65) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final]
web-app_1   |   at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.performMigration(AbstractSchemaMigrator.java:207) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final]
web-app_1   |   at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:114) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final]
web-app_1   |   at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:184) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final]
web-app_1   |   at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:73) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final]
web-app_1   |   at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:314) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final]
web-app_1   |   at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:468) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final]
web-app_1   |   at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1237) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final]
web-app_1   |   at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.2.5.RELEASE.jar!/:5.2.5.RELEASE]
web-app_1   |   at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.2.5.RELEASE.jar!/:5.2.5.RELEASE]
web-app_1   |   at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:391) 
~[spring-orm-5.2.5.RELEASE.jar!/:5.2.5.RELEASE]
web-app_1   |   ... 28 common frames omitted
web-app_1   | Caused by: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
web-app_1   |
web-app_1   | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
web-app_1   |   at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]      
web-app_1   |   at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
web-app_1   |   at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:836) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
web-app_1   |   at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:456) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
web-app_1   |   at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
web-app_1   |   at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:197) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
web-app_1   |   at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) ~[HikariCP-3.4.2.jar!/:na]
web-app_1   |   at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:354) ~[HikariCP-3.4.2.jar!/:na]
web-app_1   |   at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:202) ~[HikariCP-3.4.2.jar!/:na]
web-app_1   |   at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:473) ~[HikariCP-3.4.2.jar!/:na]
web-app_1   |   at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:554) ~[HikariCP-3.4.2.jar!/:na]
web-app_1   |   at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115) ~[HikariCP-3.4.2.jar!/:na]
web-app_1   |   at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) ~[HikariCP-3.4.2.jar!/:na]
web-app_1   |   at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final]
web-app_1   |   at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:180) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final]
web-app_1   |   at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:43) ~[hibernate-core-5.4.12.Final.jar!/:5.4.12.Final]
web-app_1   |   ... 43 common frames omitted
web-app_1   | Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
web-app_1   |
web-app_1   | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
web-app_1   |   at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_212]
web-app_1   |   at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_212]
web-app_1   |   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_212]
web-app_1   |   at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_212]
web-app_1   |   at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
web-app_1   |   at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
web-app_1   |   at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
web-app_1   |   at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
web-app_1   |   at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:91) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]      
web-app_1   |   at com.mysql.cj.NativeSession.connect(NativeSession.java:144) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
web-app_1   |   at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:956) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
web-app_1   |   at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:826) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
web-app_1   |   ... 56 common frames omitted
web-app_1   | Caused by: java.net.UnknownHostException: mysql
web-app_1   |   at java.net.InetAddress.getAllByName0(InetAddress.java:1281) ~[na:1.8.0_212]
web-app_1   |   at java.net.InetAddress.getAllByName(InetAddress.java:1193) ~[na:1.8.0_212]
web-app_1   |   at java.net.InetAddress.getAllByName(InetAddress.java:1127) ~[na:1.8.0_212]
web-app_1   |   at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:132) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]
web-app_1   |   at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:65) ~[mysql-connector-java-8.0.19.jar!/:8.0.19]      
web-app_1   |   ... 59 common frames omitted

【问题讨论】:

根据最后一个“原因”,您的连接似乎使用 mysql 作为连接字符串的主机。我会仔细检查配置。另外,我想了解更多有关主机操作系统的信息 我的操作系统是 windows 10。我已经安装了 docker 工具箱,它是 Docker 版本 19.03.1。 【参考方案1】:

web-app 没有找到 mysql,可能是 web-app 尝试连接但 mysql 尚未启动。

docker-composeweb-app配置中使用depends_on: - mysql

然后mysql容器在web-app之前起来

version: '3'
services:
    mysqldb:
        image: mysql
        container_name: mysqldbhost
        restart: always
        environment:
            MYSQL_DATABASE: docker_test
            MYSQL_ROOT_PASSWORD: mypass
        ports:
            - 3306:3306
    web-app:
        build:
            context: .
            dockerfile: Dockerfile
        image: 
            kshitij23/docker-demo:1.3
        ports:
            - "8080:8080"
        depends_on:
            - mysqldb
spring.datasource.url=jdbc:mysql://mysqldb:3306/docker_test

主机名中的连字符可能会导致问题

【讨论】:

@Abhinash 我已经尝试过了,但它不起作用。我用那个更新了我的问题。 @KSHiTiJ 你是从主机名和 docker mysql 服务名中删除 hypen 吗? 没有@Abhinash。这不是问题。我刚刚尝试了“mysqldb”,但它仍然无法正常工作。它在“jdbc:mysql”处出错。无法理解mysql不是宿主而是它的数据库名称。 @KSHiTiJ 你真的尝试使用depends_on: - mysqldb 吗?如果接受 ans 解决了您的问题,那么这也解决了您的问题,因为情况相同。好的。祝你好运 @KSHiTiJ 你可以在这里阅读详细信息docs.docker.com/compose/compose-file/#/dependson#depends_on【参考方案2】:

web-app 应用程序正在尝试连接到尚不可用的mysql-db(数据库仍在加载中)您可以根据自己的喜好使用以下任何解决方案。

    重启失败

    修改 docker-compose 文件为

       web-app:
         image: 
             kshitij23/docker-demo:1.3
         restart:on-failure
    

    睡觉

    修改环境下的docker-compose文件

      web-app:
       image:
           kshitij23/docker-demo:1.3
       environment:
        -SLEEP_LENGTH=5
    

    wait-for-it.sh 文件

    wait-for-it.sh

    这种方法需要你修改你的 Dockerfile 以及 docker-compose 文件

【讨论】:

以上是关于带有Spring引导的Docker中的Mysql连接错误的主要内容,如果未能解决你的问题,请参考以下文章

Spring boot JDBC无法连接到docker容器中的mysql

Spring Boot + MySQL docker 容器

Docker MySQL - 无法从 Spring Boot 应用程序连接到 MySQL 数据库

Spring Boot 应用程序无法连接到 Docker 中的 Redis 副本

带有 Thymeleaf、Spring 引导、Mysql 的 Ckeditor

docker-compose 中的“无法连接到本地 MySQL 服务器”