【问题标题】:Springboot Microservice running on docker not able to connect to mysql在 docker 上运行的 Spring Boot 微服务无法连接到 mysql
【发布时间】:2020-09-06 09:15:38
【问题描述】:

我正在使用 spring-boot 在使用 MySQL 的 docker 上运行我的微服务,但我的应用程序无法与 MySQL 建立连接

例外是:

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
app_1  |    at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174)
app_1  |    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64)
app_1  |    at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:836)
app_1  |    at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:456)
app_1  |    at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246)
app_1  |    at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:197)
app_1  |    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:121)
app_1  |    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:358)
app_1  |    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
app_1  |    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:477)
app_1  |    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:560)
app_1  |    ... 69 more
app_1  | Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
app_1  | 
app_1  | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
app_1  |    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
app_1  |    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
app_1  |    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
app_1  |    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
app_1  |    at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
app_1  |    at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
app_1  |    at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151)
app_1  |    at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167)
app_1  |    at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:91)
app_1  |    at com.mysql.cj.NativeSession.connect(NativeSession.java:144)
app_1  |    at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:956)
app_1  |    at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:826)
app_1  |    ... 77 more
app_1  | Caused by: java.net.ConnectException: Connection refused (Connection refused)
app_1  |    at java.net.PlainSocketImpl.socketConnect(Native Method)
app_1  |    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
app_1  |    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
app_1  |    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
app_1  |    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
app_1  |    at java.net.Socket.connect(Socket.java:589)
app_1  |    at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:155)
app_1  |    at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:65)
app_1  |    ... 80 more

docker-compose 文件是:

version: '3'

services:
  db:
    image: mysql:5.7
    restart: always
    environment:
      - MYSQL_DATABASE=inward
      # So you don't have to use root, but you can if you like
      - MYSQL_USER=root
      # You can use whatever password you like
      - MYSQL_PASSWORD=unroot
      # Password for root access
      - MYSQL_ROOT_PASSWORD=unroot
    ports:
      # <Port exposed> : < MySQL Port running inside container>
      - 3307:3306

  app:
    build:
      context: ./
      dockerfile: Dockerfile
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/inward?allowPublicKeyRetrieval=true&useSSL=false
    depends_on:
      - db
    working_dir: /app
    command: [sh, -c, 'mkdir -p ~/logs/; cd /src ; mvn clean spring-boot:run -Dspring.profiles.active=dev -DLOG_DIR=/root/logs/ -DLOG_FILE=hubstamper.log']
    ports:
      - "8080:8080"
    volumes:
      - "${HOME}/.m2:/root/.m2"

Dockerfile

FROM maven:3.5-jdk-8-alpine
COPY . /app

application.properties 文件是:

jdbcUrl=jdbc:mysql://db:3306/inward?allowPublicKeyRetrieval=true&useSSL=false
dataSource.user=root
dataSource.password=unroot
dataSource.cachePrepStmts=true
dataSource.prepStmtCacheSize=250
dataSource.prepStmtCacheSqlLimit=2048
driverClassName=com.mysql.jdbc.Driver
dataSource.driverClassName=com.mysql.jdbc.Driver

我已经尝试了链接中提到的解决方案: Communications link failure , Spring Boot + MySql +Docker + Hibernate

任何帮助都会非常有用。

【问题讨论】:

  • 我也试过了,我的意思是使用 jdbcUrl=jdbc:mysql://db:3307/inward?allowPublicKeyRetrieval=true&useSSL=false 但它不起作用
  • 使用端口3306是正确的,你使用的是docker compose网络。它在端口3307 上暴露在主机上,但这与此处无关。
  • @AnshulSharma:您确定该应用正在尝试连接到您期望的主机/端口吗?你可以通过增加日志来验证它吗?
  • 设置完整的东西可能需要一些时间。所以一开始它可能会得到“连接被拒绝”,但是在几次尝试失败后你会得到连接。
  • @wjans,是的,它正在尝试连接到 localhost:3307,但不知何故,我的 docker-machine 的 IP 地址为 192.168.99.100,我现在可以通过 MySQL 工作台连接到它。

标签: java mysql spring docker jdbc


【解决方案1】:

我可以用 docker-compose 文件解决这个问题

services:
  db:
    image: mysql:5.7
    restart: always
    environment:
      - MYSQL_DATABASE=inward
      # So you don't have to use root, but you can if you like
      - MYSQL_USER=root
      # You can use whatever password you like
      - MYSQL_PASSWORD=unroot
      # Password for root access
      - MYSQL_ROOT_PASSWORD=unroot
    ports:
      # <Port exposed> : < MySQL Port running inside container>
      - 3307:3306

  app:
    build:
      context: ./
      dockerfile: Dockerfile
    depends_on:
      - db
    working_dir: /app
    command: [sh, -c, 'mkdir -p ~/logs/; cd /src ; mvn clean spring-boot:run -Dspring.profiles.active=local -DLOG_DIR=/root/logs/ -DLOG_FILE=hubstamper.log']
    ports:
      - 8080:8080
    volumes:
      - "${HOME}/.m2:/root/.m2"

和应用程序-local.properties 文件

jdbcUrl=jdbc:mysql://db:3306/inward?allowPublicKeyRetrieval=true&useSSL=false
dataSource.user=root
dataSource.password=unroot
dataSource.cachePrepStmts=true
dataSource.prepStmtCacheSize=250
dataSource.prepStmtCacheSqlLimit=2048
driverClassName=com.mysql.jdbc.Driver
dataSource.driverClassName=com.mysql.jdbc.Driver

和docker文件

FROM maven:3.5-jdk-8-alpine
COPY . /app

请确保每次更改代码中的任何内容时,删除旧的 docker 映像并创建一个新映像(这也是我在方法中缺少的)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-29
    • 1970-01-01
    • 2019-10-11
    • 2021-09-20
    • 2023-02-23
    • 2020-07-12
    • 2021-07-02
    • 2020-07-24
    相关资源
    最近更新 更多