Shi*_*ang 12 java mysql spring jenkins docker
当我在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
Run Code Online (Sandbox Code Playgroud)
当运行本地测试时,它们全部通过,使用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
Run Code Online (Sandbox Code Playgroud)
URL中的MySQL是MySQL docker容器名称.如果localhost在docker container inspect mysql错误消息中更改它或私有IP 是相同的,而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)
Run Code Online (Sandbox Code Playgroud)
对于私人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
Run Code Online (Sandbox Code Playgroud)
我认为不同的是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
Run Code Online (Sandbox Code Playgroud)
当我在IntelliJ中运行JUnit测试时,它有时会在本地环境中失败.错误日志如下:
Caused by: org.h2.jdbc.JdbcSQLException: Schema "DATABASE" not found; SQL statement:
TRUNCATE TABLE database.data_log
Run Code Online (Sandbox Code Playgroud)
我已经搜索了这个问题,据说默认情况下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 中的 JDBC URL 的主机更改application.properties为 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
...
Run Code Online (Sandbox Code Playgroud)
我的结论是:
从镜像构建的 Jenkins 容器能够通过 docker 桥接网络上的容器名称或私有地址与 MySQL 容器进行通信。然而,由于 Jenkins 构建的应用程序无法做到这一点。由于MySQL容器端口已绑定到主机,因此应用程序可以通过主机端口与MySQL容器通信。
如果结论有误,欢迎批评指正。
| 归档时间: |
|
| 查看次数: |
3017 次 |
| 最近记录: |