Docker 上的 Spring Boot 无法连接到 MySQL

Posted

技术标签:

【中文标题】Docker 上的 Spring Boot 无法连接到 MySQL【英文标题】:SpringBoot on Docker unable to connect to MySQL 【发布时间】:2019-01-29 12:41:48 【问题描述】:

我使用 mysql 为我的 SpringBoot 应用程序编写了 docker compose。当我最终运行 docker-compose up 时出现错误:

 The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
      at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80) ~[spring-jdbc-4.3.17.RELEASE.jar!/:4.3.17.RELEASE]
      at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:325) ~[spring-jdbc-4.3.17.RELEASE.jar!/:4.3.17.RELEASE]
      ... 69 common frames omitted
  Caused by: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

  The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
      at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:172) ~[mysql-connector-java-8.0.11.jar!/:8.0.11]
      at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64) ~[mysql-connector-java-8.0.11.jar!/:8.0.11]
      at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:862) ~[mysql-connector-java-8.0.11.jar!/:8.0.11]
      at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:444) ~[mysql-connector-java-8.0.11.jar!/:8.0.11]
      at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:230) ~[mysql-connector-java-8.0.11.jar!/:8.0.11]
      at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:226) ~[mysql-connector-java-8.0.11.jar!/:8.0.11]
      at java.sql.DriverManager.getConnection(DriverManager.java:664) ~[na:1.8.0_111]
      at java.sql.DriverManager.getConnection(DriverManager.java:208) ~[na:1.8.0_111]
      at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:153) ~[spring-jdbc-4.3.17.RELEASE.jar!/:4.3.17.RELEASE]
      at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriver(DriverManagerDataSource.java:144) ~[spring-jdbc-4.3.17.RELEASE.jar!/:4.3.17.RELEASE]
      at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnectionFromDriver(AbstractDriverBasedDataSource.java:196) ~[spring-jdbc-4.3.17.RELEASE.jar!/:4.3.17.RELEASE]
      at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnection(AbstractDriverBasedDataSource.java:159) ~[spring-jdbc-4.3.17.RELEASE.jar!/:4.3.17.RELEASE]
      at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111) ~[spring-jdbc-4.3.17.RELEASE.jar!/:4.3.17.RELEASE]
      at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77) ~[spring-jdbc-4.3.17.RELEASE.jar!/:4.3.17.RELEASE]
      ... 70 common frames omitted
  Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure

起初我认为原因是数据库,但我设法运行应用程序的本地实例并连接到 docker mysql。 接下来,我假设 spring 应用程序在启动并运行之前尝试连接到 mysql,但我重新启动了应用程序(mysql 已经在运行)并得到了同样的错误。 目前我认为这可能是由 windows10 防火墙引起的,但我的想法很少。

Dockerfile:

FROM java:8
LABEL maintainer="maciej"
WORKDIR /app
COPY target/kamienica.jar /app/kamienica.jar
ENTRYPOINT ["java", "-jar","kamienica.jar", "--spring.profiles.active=docker"]

docker-compose.yml

version: '3'

services:
  mysql-docker-container:
    image: mysql:latest
    environment:
      - MYSQL_ROOT_PASSWORD=maciej
      - MYSQL_DATABASE=kamienica
      - MYSQL_USER=maciej
      - MYSQL_PASSWORD=maciej
    volumes:
      - /data/mysql
    ports:
    - 3333:3306
    container_name: kamienica-db
  kamienica-app:
    image: kamienica-image
    build:
      context: ./
      dockerfile: Dockerfile
    depends_on:
      - mysql-docker-container
    ports:
      - 8080:8080
    volumes:
      - /data/spring-boot-app
    container_name: kamienica-app

和应用程序-docker.properties:

jdbc.url = jdbc:mysql://kamienica-db:3333/kamienica?useSSL=false&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
jdbc.username = maciej
jdbc.password = maciej
hibernate.show_sql = true
hibernate.format_sql = true
hibernate.hbm2ddl.auto=create-drop
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.current_session_context_class=thread
hibernate.connection.characterEncoding=UTF-8
hibernate.connection.charSet=UTF-8

【问题讨论】:

您的 MySQL 数据库已关闭 那我怎么能通过 MySQL 工作台以及指向它的应用程序的本地实例连接到它? Maciek,很可能是数据库初始化过程。为什么其他工具可能正在工作?当您第一次启动您的应用程序时,Java 还无法连接到数据库,然后您尝试使用其他工具,但数据库已经启动并运行,因此其他工具没有问题。这是一个非常常见的 compose 文件配置错误。如果有兴趣,可以提供帮助。 查看我对一个非常相似的问题there 的回答,看看我的意思。 然后尝试 exec'ing 进入 Java 容器,ping 从 Java 容器内部进入 DB 容器,看看它是否至少可以访问 - 如果不是,那么你是对的,并且这意味着一些网络问题。 【参考方案1】:

尝试将 url 更改为您的属性文件

jdbc:mysql://mysql-docker-container:3306/kamienica

【讨论】:

【参考方案2】:

jdbc:mysql://[mysql-docker-container-name]:[mysql-port]/[db-name]

在你的 docker-compose.yml 中 mysql-docker-container-name 是 mysql-docker-container

所以改变你的spring boot application.properties文件mysql url如下

jdbc:mysql://mysql-docker-container:3306/kamienica

【讨论】:

以上是关于Docker 上的 Spring Boot 无法连接到 MySQL的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Spring Boot 应用程序连接到 Docker 映像

如何将我的 Spring Boot 应用程序连接到 Docker 上的 Redis 容器?

Docker:无法连接到弹性搜索表单spring boot docker image

Spring Boot + MySQL + Docker Compose - 无法使 Spring Boot 连接到 MySQL

docker-compose spring boot无法连接到Postgres [重复]

Spring Boot无法连接到同一网络的docker中的mysql