首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Docker组合Java应用程序&基于JDBC的MySql连接问题

Docker组合Java应用程序&基于JDBC的MySql连接问题
EN

Stack Overflow用户
提问于 2022-04-27 14:39:28
回答 1查看 387关注 0票数 1

当在docker容器中实现Java应用程序时,以及在自己的docker容器中配置的MySQL数据库与Docker组合一起实现时,在使用jdbc创建到数据库的连接时,总是会发生以下错误:

代码语言:javascript
复制
currency_server_v0_1  | com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
    currency_server_v0_1  |
    currency_server_v0_1  | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
    currency_server_v0_1  |         at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174)
    currency_server_v0_1  |         at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64)
    currency_server_v0_1  |         at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:836)
    currency_server_v0_1  |         at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:456)
    currency_server_v0_1  |         at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246)
    currency_server_v0_1  |         at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:197)
    currency_server_v0_1  |         at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:677)
    currency_server_v0_1  |         at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:228)
    currency_server_v0_1  |         at Test.main(Test.java:22)
    currency_server_v0_1  | Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
    currency_server_v0_1  |
    currency_server_v0_1  | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
    currency_server_v0_1  |         at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    currency_server_v0_1  |         at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:78)
    currency_server_v0_1  |         at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    currency_server_v0_1  |         at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
    currency_server_v0_1  |         at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
    currency_server_v0_1  |         at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
    currency_server_v0_1  |         at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
    currency_server_v0_1  |         at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151)
    currency_server_v0_1  |         at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167)
    currency_server_v0_1  |         at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:91)
    currency_server_v0_1  |         at com.mysql.cj.NativeSession.connect(NativeSession.java:144)
    currency_server_v0_1  |         at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:956)
    currency_server_v0_1  |         at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:826)
    currency_server_v0_1  |         ... 6 more
    currency_server_v0_1  | Caused by: java.net.ConnectException: Connection refused
    currency_server_v0_1  |         at java.base/sun.nio.ch.Net.connect0(Native Method)
    currency_server_v0_1  |         at java.base/sun.nio.ch.Net.connect(Net.java:576)
    currency_server_v0_1  |         at java.base/sun.nio.ch.Net.connect(Net.java:565)
    currency_server_v0_1  |         at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:588)
    currency_server_v0_1  |         at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:333)
    currency_server_v0_1  |         at java.base/java.net.Socket.connect(Socket.java:645)
    currency_server_v0_1  |         at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:155)
    currency_server_v0_1  |         at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:65)
    currency_server_v0_1  |         ... 9 more
    currency_server_v0_currency_server_v0_1 exited with code 0

相应的Docker文件和Java代码如下所示: docker-compose.yml: version:"3.7“

代码语言:javascript
复制
services:
  currency_server_v0:
    build: .
    ports:
      - 8080:8080
    depends_on:
      - mysqldb
    networks:
      currency-mysql:

  mysqldb:
    image: mysql:5.7
    container_name: mysqldb
    ports:
      - 3306:3306
    networks:
      currency-mysql:
    volumes:
      - db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=currency_server_db
      - MYSQL_USER= admin
      - MYSQL_PASSWORD= admin
volumes:
  db:
networks:
  currency-mysql:

Java中的JDBC连接:

代码语言:javascript
复制
try (Connection conn = DriverManager.getConnection(
        "jdbc:mysql://mysqldb:3306/currency_server_db", "root", "root");
     Statement stmt = conn.createStatement();
) {
    String sql = "CREATE TABLE TEST " +
            "(id INTEGER not NULL, " +
            " PRIMARY KEY ( id ))";

    stmt.executeUpdate(sql);
    System.out.println("Created table in given database...");
} catch (SQLException e) {
    e.printStackTrace();
}

Dockerfile:

代码语言:javascript
复制
FROM openjdk:16-alpine3.13
COPY target/currency_server_v0-1.0-SNAPSHOT-jar-with-dependencies.jar app.jar
ENTRYPOINT ["java","-jar", "app.jar"]

有人有或知道这个问题吗?谢谢你的回答。

EN

Stack Overflow用户

发布于 2022-04-27 17:20:16

您的服务启动速度比MySql快,尽管depends_on不知道如何检查容器是否准备好接受连接。您可以在服务Dockerfile中实现等待行为,也可以在Java中这样做:

代码语言:javascript
复制
public static void main(final String[] args) {
    waitForServer("mysqldb", 3306, 10_000);
}

public static void waitForServer(String host, int port, int timeout) {
    long start = System.currentTimeMillis();
    while (portUnavailable(host, port)) {
        System.out.println("Waiting for port to open: " + port);
        if (System.currentTimeMillis() - start > timeout) {
            throw new Error("Timeout waiting for port to open: " + port);
        }
    }
}

private static boolean portUnavailable(String host, int port) {
    try (Socket s = new Socket(host, port)) {
        return false;
    } catch (Exception e) {
        return true;
    }
}
票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72030685

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档