Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Docker网桥网络时,无法在集成测试中获取JDBC连接_Java_Mysql_Spring_Docker_Jenkins - Fatal编程技术网

Java 使用Docker网桥网络时,无法在集成测试中获取JDBC连接

Java 使用Docker网桥网络时,无法在集成测试中获取JDBC连接,java,mysql,spring,docker,jenkins,Java,Mysql,Spring,Docker,Jenkins,当我在本地运行maven测试时,通过。但在CI服务器上运行时出现此错误 Error Message Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection Stacktrace org.springframework.transaction.Cann

当我在本地运行
maven测试时,
通过。但在CI服务器上运行时出现此错误

Error Message
Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection
Stacktrace
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection
Caused by: org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: 
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.
Caused by: java.net.UnknownHostException: mysql
运行本地测试时,它们都通过了,使用IntelliJ IDEA提供的maven测试默认设置。
由于错误是关于数据库连接的,所以我检查了Jenkins对数据库插件的审计。连接成功

我的
应用程序.properties
中的连接参数也与此对应

spring.datasource.url=jdbc:mysql://mysql:3306/database?useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.maxActive=5
URL中的MySQL是MySQL docker容器名。如果使用
localhost
docker container inspect mysql
中的私有IP进行更改,则错误消息是相同的,而最后两行的Stacktrace略有不同

对于本地主机

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
Caused by: java.net.ConnectException: Connection refused (Connection refused)
对于私有IP

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. 
Caused by: java.net.SocketTimeoutException: connect timed out
我认为不同的是URL中的主机,localhost用于本地测试。 而Jenkins服务器使用Docker桥网络

容器状态为:

docker container ls
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS
                                          NAMES
51ea7c7864a4        mysql:5.7             "docker-entrypoint.s…"   19 hours ago        Up 19 hours         0.0.0.0:3306->3306/tcp                             mysql
de364f7b5eaf        maven:3-jdk-8         "/usr/local/bin/mvn-…"   21 hours ago        Up 21 hours
                                          optimistic_stallman
a6545591e358        jenkinsci/blueocean   "/sbin/tini -- /usr/…"   43 hours ago        Up 43 hours         0.0.0.0:50000->50000/tcp, 0.0.0.0:2048->8080/tcp   frosty_cray
当我在IntelliJ中运行JUnit测试时,它有时会在本地环境中失败。错误日志如下所示:

Caused by: org.h2.jdbc.JdbcSQLException: Schema "DATABASE" not found; SQL statement:
TRUNCATE TABLE database.data_log 
我已经搜索了这个问题,据说h2数据库默认使用大写。 在运行
maven测试之后,如果再次在IDE中运行JUnit测试,这个问题将消失。但这与根本原因无关

搜索错误消息,找到一些类似的问题,但有不同的嵌套异常:

所有这些都是关于
嵌套异常是javax.persistence.PersistenceException

但是
嵌套异常是org.hibernate.exception.JDBCConnectionException:
是我的情况。 阅读
然而,由于插件连接正常,这意味着从Jenkins容器到MySQL容器的连接正常

总结:
1.maven通过的本地测试
2.Jenkins插件连接MySQL成功
3.从Jenkins运行时集成测试失败

4.本地测试环境为WIN10 64位;Jenkins在Ubuntu 16.04 64位服务器上的docker容器中运行,MySQL 5.7容器连接到同一网桥网络。

您应该将docker容器MySQL端口绑定到VM中的一个端口

这在下面的线程中得到了很好的解释

值得一试……
多亏了。我们将问题缩小到与URL主机相关的内容。
简单的答案是将spring boot
应用程序.properties中JDBC URL的主机更改为docker主机IP地址。从
spring.datasource.url=jdbc:mysql://mysql:3306/database?


spring.datasource.url=jdbc:mysql://172.17.0.1:3306/database?


这篇文章也有助于最终解决问题

ip addr show docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default        
    ...   
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       ...
ip地址显示docker0
4:docker0:mtu 1500 qdisc noqueue state UP组默认值
...   
inet 172.17.0.1/16 brd 172.17.255.255范围全局docker0
...
我的结论是:
从映像构建的Jenkins容器能够通过其容器名称或docker bridge网络上的私有地址与MySQL容器通信。然而,由于Jenkins构建的应用程序无法做到这一点。 由于MySQL容器端口已绑定到主机,因此应用程序可以通过主机端口与MySQL容器通信


如果结论是错误的,欢迎评论。

您可以检查一些可能有助于解决此问题的内容

  • 在application.properties中,尝试使用docker主机IP地址

    注: 在docker运行或docker文件中的端口时,需要映射IP和端口。并在容器之间使用相同的docker网络

  • 验证您的服务器应用程序是否可以访问mysql,反之亦然。进入docker容器并尝试ping


如果您正在使用Spring boot并在docker中运行测试数据库,我建议您查看一下,下面是如何以最佳方式使用它的说明:(您可以跳过Spock部分)@MaxFarsikov
testcontainer
看起来很酷,但是,在阅读了他们的文档和示例之后,我没有足够的信心在当前项目中使用它。也许我以后会在某个附带项目上尝试。错误是说,
没有发送任何数据包
,这表明您的应用程序和mySQL没有相互通信……您还提到Jenkins和mySQL正在相互通信。。。这很好……但是您确认了mySQL和您的应用程序(部署在远程服务器上的位置)是否正在相互通信吗??更多信息请点击这里@Rohittomas我同意你的观点。问题可能存在于MySQL和应用程序之间。我读过那篇文章,并在我的文章中引用了它。但还是不知道去哪里查。本地测试有时会失败,但在我运行
maven测试后会通过,稍后会通过一段时间。。。。该应用程序正在本地运行,运行良好??应用程序托管在另一台服务器上,仅在该服务器上或在本地服务器上失败??最后,它什么时候会失败有时候你调试过那个场景吗??maven测试也将通过-->您是否只为这种情况编写了连接???
docker run-d--name mysql-p 3306:3306-e mysql\u ROOT\u PASSWORD=PASSWORD mysql:5.7
已经运行如果是端口问题,插件将无法成功连接。@ShiheZhang我刚刚编辑了我的答案。应来自jdbc:mysql://mysql:3306/DATABASE_URI_PATH 对于jdbc:mysql://192.168.99.100:3306/DATABASE_URI_PATH
spring.datasource.url = jdbc:mysql://mysql:3306/DATABASE_URI_PATH
spring.datasource.url = jdbc:mysql://192.168.99.100:33060/DATABASE_URI_PATH