【发布时间】:2018-12-12 18:06:22
【问题描述】:
当我在本地运行 maven test 时通过。但是当我在 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 Audit 对数据库插件进行了检查。连接成功!
我application.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 test后,如果再次在IDE中运行JUnit测试就会出现这个问题。但这应该与根本原因无关。
搜索错误信息,找到一些类似的问题,但嵌套的异常不同:
SpingREST: Could not open JPA EntityManager for transaction; nested exception is org.hiberna
都是关于nested exception is javax.persistence.PersistenceException
但是nested exception is org.hibernate.exception.JDBCConnectionException: 是我的情况。
阅读Connect Java to a MySQL database
但是由于该插件连接正常,意味着从 Jenkins 容器到 MySQL 容器的连接很好。
总结:
1. 使用 maven 进行本地测试通过
2. Jenkins插件连接MySQL成功
3. 从 Jenkins 运行时集成测试失败
4.本地测试环境为WIN10 64bit; Jenkins 在 Ubuntu 16.04 64 位服务器上的 docker 容器中运行,MySQL 5.7 容器连接到同一个桥接网络。
【问题讨论】:
-
如果您使用 Spring boot 并在 docker 中运行您的测试数据库,我建议您查看 testcontainers.org ,这里是如何以最佳方式使用它的说明:@987654328 @(你可以跳过 Spock 部分)
-
@MaxFarsikov
testcontainer看起来很酷,但是,在阅读了他们的文档和示例之后,我没有足够的信心在当前项目中使用它。也许我稍后会在一些附带项目上尝试一下。 -
错误是说
no packets were sent,表明你的应用程序和mySQL没有互相交谈......你也提到Jenkins和mySQL正在互相交谈......那就是很好...但是您是否确认mySQL and your application(它部署在远程服务器上的哪个位置)正在相互交谈?检查此以获取更多信息stackoverflow.com/questions/2983248/… -
@rohitthomas 我同意你的看法。问题可能存在于 MySQL 和应用程序之间。我已经阅读了那篇文章并在我的文章中提到了它。不过,不知道在哪里检查。本地测试有时会失败,但在我运行
maven test后会通过,稍后会通过一段时间。 -
我需要了解的几件事......该应用程序在您的本地运行并且工作正常??该应用程序托管在另一台服务器上,它只在那里或本地失败?最后它什么时候失败有时你调试过那个场景?? maven 测试也将通过 --> 您是否只为这种情况编写了连接??
标签: java mysql spring docker jenkins