【问题标题】:Connection refused when connecting to host mysql db from docker container从 docker 容器连接到主机 mysql db 时连接被拒绝
【发布时间】:2020-09-21 00:59:00
【问题描述】:

我正在尝试从运行在 docker 容器内的 spring 应用程序连接到在主机 (localhost) 上运行的 mysql 服务器

这是我的 Dockerfile

FROM openjdk:11
ADD build/libs/demo-0.0.1-SNAPSHOT.jar demo.jar
EXPOSE 8000
RUN mkdir -p tmp/scripts
RUN mkdir -p tmp/logs
ENTRYPOINT ["java","-jar","/demo.jar"]

我正在使用 Docker desktop for mac v2.3.0.3,引擎版本为 19.03.8

这是可能的 hikariCP 数据源连接属性

spring.datasource.jdbcUrl=jdbc:mysql://**host.docker.internal:3306**/freshid
spring.datasource.username=sa
spring.datasource.password=test

当我构建docker build -f Dockerfile -t demo . 并以docker run -p 8000:8000 demo 运行映像时

应用程序启动时出现以下错误

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:174)
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64)
    at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:835)
    at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:455)
    at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:240)
    at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:199)
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:354)
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:202)
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:473)
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:554)
    ... 64 common frames omitted
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: 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 java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
    at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
    at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
    at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151)
    at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167)
    at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:91)
    at com.mysql.cj.NativeSession.connect(NativeSession.java:152)
    at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:955)
    at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:825)
    ... 72 common frames omitted
Caused by: java.net.ConnectException: Connection refused (Connection refused)
    at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)
    at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)
    at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)
    at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:403)
    at java.base/java.net.Socket.connect(Socket.java:609)
    at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:155)
    at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:65)
    ... 75 common frames omitted

【问题讨论】:

  • jdbc:mysql://host.docker.internal:3306/db - 这是我的连接字符串
  • 请注意,特殊主机名 host.docker.internal 长期以来一直是仅适用于 macOS 版本的 Docker 的功能。确保您使用的不是旧版本的 Docker,并且您使用的操作系统实际上支持此功能。 Windows:this page 说:“这是出于开发目的,不适用于 Docker Desktop for Windows 之外的生产环境。”
  • 如前所述,我正在为 MAC v2.3.0.3 使用 Docker 桌面,引擎版本为 19.03.8
  • 您是否还配置 MySQL 以允许远程连接?因为默认情况下它只允许来自 localhost 的连接(并且你的 Docker 容器看起来像是 MySQL 的外部系统)。

标签: java mysql spring docker docker-networking


【解决方案1】:

我会建议一个简单的解决方案。

第 1 步:Turboshooting:尝试在容器外部的机器中运行 springboot 应用程序。如果工作正常,那么您的应用程序没有问题。 (确保在本地测试时将数据库连接字符串从 host.docker.internal 更改为 localhost

第二步:当你使用命令式命令运行Docker Container时,请暴露你的DB端口,默认为3306以防mysql

docker run -p 8000:8000 -p 3306:3306 demo

这应该可以解决您的问题??

【讨论】:

  • 应用程序未在端口 3306 上侦听,并且您不需要 -p 选项来建立出站连接。 (确实,如果宿主机运行的是 MySQL 实例,这会导致容器无法启动。)
【解决方案2】:

我卸载并重新安装了 docker (19.03.8) 并且它工作正常。最后的连接字符串是jdbc:mysql://host.docker.internal:3306/db。这并不能得出任何技术正确性的结论,但它确实有效。谢谢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-26
    • 1970-01-01
    • 2019-10-20
    • 2018-10-23
    • 2021-12-31
    • 2021-08-15
    • 1970-01-01
    • 2021-06-11
    相关资源
    最近更新 更多