当前位置: 首页 > 知识库问答 >
问题:

Docker Compose Java应用程序

宫高义
2023-03-14

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

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:版本:“3.7”

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连接:

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:

FROM openjdk:16-alpine3.13
COPY target/currency_server_v0-1.0-SNAPSHOT-jar-with-dependencies.jar app.jar
ENTRYPOINT ["java","-jar", "app.jar"]

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

共有1个答案

乐修远
2023-03-14

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

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;
    }
}
 类似资料:
  • Application是CatLib程序的核心,也是所谓的程序入口。应用程序通过引导来加载服务提供者和其他一些必须的资源。应用程序在一般情况下只允许启动一个,且只能在主线程中启动。 在任何位置,您可以通过App全局变量访问应用程序。 启动流程 Application.Bootstrap -> Application.Register -> Application.Init Application.

  • Leafpad Leafpad是一个十分小巧、快捷的图形界面文本编辑器,它可以用于作笔记或者编辑文件。你可以在菜单中找到它,或者直接在命令行中指定Leafpad编辑文件: $ leafpad Templates/script-shell.sh ISO 大师 —— 创建并且编辑ISO文件 ISO大师是一个可以创建、操作、编辑ISO镜像的图形工具,你可以储存或刻录生成的ISO文件。这个软件简单、直观

  • The best software in the world only sucks. The worst software is significantly worse than that. — Luke Kanies 在本章中,我们将学习如下内容: 管理 Apache 服务 创建 Apache 虚拟主机 创建 Nginx 虚拟主机 创建 MySQL 数据库及用户 管理 Drupal 站点 管理

  • 下图说明数据流如何贯穿整个系统: index.php 作为前端控制器,初始化运行 CodeIgniter 所需要的基本资源。 Router 检查 HTTP 请求,以确定谁来处理请求。 如果缓存(Cache)文件存在,它将绕过通常的系统执行顺序,被直接发送给浏览器。 安全(Security)。应用程序控制器(Application Controller)装载之前,HTTP 请求和任何用户提交的数据将

  • 我有一个Winforms应用程序,它目前正在使用application Insights SDK捕获错误日志、事件、异常、表单视图和另一个遥测。App Center现在支持WinForms应用程序,它还支持将遥测数据导出到应用程序洞察中。我现在的问题是,我是否应该从WinForms应用程序中删除Application Insights SDK,而使用AppCenter SDK?这样做有什么好处吗?

  • 下图说明了整个系统的数据流程: index.php 文件作为前端控制器,初始化运行 CodeIgniter 所需的基本资源; Router 检查 HTTP 请求,以确定如何处理该请求; 如果存在缓存文件,将直接输出到浏览器,不用走下面正常的系统流程; 在加载应用程序控制器之前,对 HTTP 请求以及任何用户提交的数据进行安全检查; 控制器加载模型、核心类库、辅助函数以及其他所有处理请求所需的资源;

  • 我有一个nodejs应用程序,它只不过是一个使用微软botbuilder框架构建的机器人。我创建了azure应用程序服务来托管此应用程序。我想找到一种方法,将所有应用程序日志和web服务器日志(如果可能的话)持久化到某个持久化存储中。就像本地web应用程序一样,我们可以在应用程序服务器上查找日志 在做了一些研究之后,我找到了微软关于这方面的官方文件,但看起来它有以下局限性。 我们不能使用应用程序服

  • 主要内容:XML 文档实例,在 HTML div 元素中显示第一个 CD,实例,添加导航脚本,实例,当点击 CD 时显示专辑信息本章演示一些基于 XML, HTML, XML DOM 和 JavaScript 构建的小型 XML 应用程序。 XML 文档实例 在本应用程序中,我们将使用 "cd_catalog.xml" 文件。 在 HTML div 元素中显示第一个 CD 下面的实例从第一个 CD 元素中获取 XML 数据,然后在 id="showCD" 的 HTML 元素中显示数据。displ