![](/img/trans.png)
[英]JDBCConnectionException: Unable to acquire JDBC Connection when using JPA
[英]Unable to acquire JDBC Connection on integration test when using Docker bridge network
当我在本地运行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容器名称。 如果在docker container inspect mysql
使用localhost
或私有IP更改它,则docker container inspect mysql
的错误消息是相同的,而Stacktrace在最后两行有点不同。
对于localhost
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测试,则会出现此问题。 但这应该与根本原因无关。
搜索错误消息,找到一些类似的问题但具有不同的嵌套异常:
无法打开JPA EntityManager进行交易; 嵌套异常是javax.persistence.PersistenceException
SpingREST:无法打开JPA EntityManager进行事务处理; 嵌套异常是org.hiberna
无法打开JPA EntityManager进行交易; org.hibernate.exception.GenericJDBCException:无法打开连接
所有这些都是关于nested exception is javax.persistence.PersistenceException
但是nested exception is org.hibernate.exception.JDBCConnectionException:
是我的情况。 阅读将Java连接到MySQL数据库
但是因为该插件连接正常,意味着从Jenkins容器到MySQL容器的连接很好。
总结:
1. maven的本地测试通过
2. Jenkins插件连接MySQL成功
3.从Jenkins运行时集成测试失败
4.本地测试环境是WIN10 64bit; Jenkins在Ubuntu 16.04 64位服务器上的docker容器中运行,MySQL 5.7容器连接到同一个桥接网络。
感谢@ rohit-thomas 。 我们将问题缩小到与URL主机相关的问题。
简单的答案是将spring boot application.properties
中的JDBC URL主机更改为docker主机IP地址。 从
spring.datasource.url=jdbc:mysql://mysql:3306/database?
至
spring.datasource.url=jdbc:mysql://172.17.0.1:3306/database?
从Docker容器内部,如何连接到本机的本地主机?
这篇文章也有助于作为最终解决方案。
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
...
我的结论是:
从映像构建的Jenkins容器可以使用其容器名称或docker bridge网络上的私有地址与MySQL容器进行通信。 但是,由于Jenkins构建的应用程序无法做到这一点。 由于MySQL容器端口已绑定到主机,因此应用程序可以通过主机端口与MySQL容器通信。
如果结论错误,欢迎提出意见。
您可以检查的一些内容可能有助于您解决此问题。
在application.properties中尝试使用docker主机IP地址。
从
spring.datasource.url = jdbc:mysql://mysql:3306/DATABASE_URI_PATH
至
spring.datasource.url = jdbc:mysql://192.168.99.100:33060/DATABASE_URI_PATH
注意:在docker run或docker文件中的端口时,您需要映射IP和端口。并在容器中使用相同的docker网络。
验证服务器应用程序是否可以访问您的mysql,反之亦然。 进入docker容器并尝试ping。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.