如何连接 Java 容器和 MySQL 容器?

Posted

技术标签:

【中文标题】如何连接 Java 容器和 MySQL 容器?【英文标题】:How to connect a Java container with a MySQL container? 【发布时间】:2021-09-15 20:36:54 【问题描述】:

我正在阅读official documentation 并停留在以下步骤

文档中使用的应用程序支持诸如mysql_HOSTMYSQL_USER等环境变量,但我的程序是Java,不支持它们。 相反,我在 java 代码中使用以下连接字符串来连接数据库:

return new DefaultConfiguration().set(DriverManager.getConnection(
                                            "jdbc:mysql://127.0.0.1:3306/test?serverTimezone=UTC",
                                            "root",
                                            "111111"))
                                 .set(SQLDialect.MYSQL);

那么我应该如何更改连接字符串?因为现在连接失败如下图

Jul 05, 2021 12:31:35 AM org.jooq.tools.JooqLogger error

SEVERE: Error in file: /app/build/tmp/generateJooq/config.xml. Error : 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.

com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

对于host,我应该将其更改为localhost吗?我在 mysql 命令行中运行 select user(); 得到以下结果

+----------------+
| user()         |
+----------------+
| root@localhost |
+----------------+

这是否意味着主机是localhost

但是,当我运行show variables; 时,hostname 的值是1f1632505b1f,那么为什么会有两个主机名呢?

对于端口,我检查了 MySQL 映像,它暴露了 3306,所以我认为这部分我不需要更改,对吗?

对于数据库名称,我创建了一个名为test 的数据库,所以我认为这部分应该没问题。用户名和密码相同。

检查 MySQL 容器:

my.cnf 文件指定bind-address=0.0.0.0

mysql容器的日志:

【问题讨论】:

一个好的做法是从您引用的environment variables 构造连接字符串,而不是在应用程序中硬编码某些内容。 Docker 中的localhost 一般表示“这个容器”;像Networking in Compose 这样的文档描述了如何在容器之间建立连接。 @DavidMaze 感谢您的建议。你是对的,我已经改为使用环境变量。 【参考方案1】:

您可能必须配置您的 MySQL 服务器以侦听所有地址,例如通过在 docker 容器中编辑此文件

/etc/mysql/my.cnf

并指定

bind-address=0.0.0.0

另见https://serverfault.com/q/139323

【讨论】:

恐怕它对我不起作用。请查看更新,我在其中添加了my.cnf 文件和日志。同样的错误仍然出现。 (我使用jdbc:mysql://amazing_herschel:3306/test?serverTimezone=UTC 作为连接字符串,其中amazing_herschel 是mysql 容器的名称。由于它们在同一个docker 网络中,我想它应该可以工作,对吗?)谢谢! 顺便说一句,mysql容器不需要暴露端口,因为java容器在docker网络中访问它,对吗? 您是否尝试过连接到localhost【参考方案2】:

原来我忘记先运行迁移了……

在我的Dockerfile 中,我应该先运行./gradlew flywayMigrate,然后运行./gradlew runApp(这是JavaExec 类型的任务),但我忘记了前者,因此出现了错误。

错误只提到数据库连接失败,而不是关于迁移的任何内容,这是违反直觉的..

感谢大家的帮助!

【讨论】:

以上是关于如何连接 Java 容器和 MySQL 容器?的主要内容,如果未能解决你的问题,请参考以下文章

如何将两个NodeJS docker容器连接在一起?

如何在搬运工中将两个 docker 容器相互连接

如何通过 SSH 连接到 MySQL Docker 容器?

如何解决 docker 容器延迟

Kubernetes pod 应用程序与不在容器上的 Mysql 数据库的连接

如何在Mysql的Docker容器启动时初始化数据库