Не удалось получить соединение JDBC в тесте интеграции при использовании сети моста 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
при запуске локального теста все они прошли, используется настройка теста maven по умолчанию, предоставляемая IntelliJ IDEA.
Поскольку ошибка жалуется на подключение к базе данных, поэтому я проверил Jenkins Audit на плагин базы данных. Соединение Успешно!
параметр подключения в my 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
MySQL в URL-адресе является именем контейнера MySQL docker. Если изменить его с 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 bridge.
в состояние контейнера:
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
когда я запускаю тест JUnit в IntelliJ, он иногда терпит неудачу в локальной среде. Журнал ошибок выглядит так:
Caused by: org.h2.jdbc.JdbcSQLException: Schema "DATABASE" not found; SQL statement:
TRUNCATE TABLE database.data_log
Я искал проблему, он сказал, что база данных h2 использует верхний регистр по умолчанию.
После бега maven test
, эта проблема будет идти, если снова запустить тест JUnit в IDE. Но это не должно быть связано с первопричиной.
поиск в сообщении об ошибке найдите аналогичный вопрос, но с другим вложенным исключением:
не удалось открыть JPA EntityManager для транзакции; вложенным исключением является javax.стойкость.PersistenceException
SpingREST: не удалось открыть JPA EntityManager для транзакции; вложенным исключением является org.hiberna
не удалось открыть JPA EntityManager для транзакции; org.зимовать.исключение.GenericJDBCException: не удалось открыть соединение
не удалось открыть JPA EntityManager для транзакции весной
все они-о nested exception is javax.persistence.PersistenceException
Но!--12--> моя ситуация.
Читать подключение Java к базе данных MySQL
однако, поскольку этот плагин подключается нормально, означает, что соединение из контейнера Jenkins с контейнером MySQL в порядке.
подведем итог:
1. локальный тест с Maven прошел
2. Плагин Jenkins подключается к MySQL успех
3. Интеграционный тест не выполняется при запуске из Jenkins
4. локальная тестовая среда WIN10 64bit; Дженкинс работает в контейнере docker на Ubuntu 16.04 64bit server, с MySQL 5.7 контейнер подключается к той же сети моста.
3 ответов
вы должны привязать порт mysql контейнера docker к порту в VM.
Это хорошо объясняется в приведенном ниже потоке.
стоит попробовать...
Как подключиться к MySQL DB, работающему как контейнер в docker?
спасибо @rohit-thomas. Мы сужаем вопрос до чего-то, связанного с хостом URL-адреса.
Простой ответ-изменение хоста URL JDBC в весенней загрузке application.properties
к IP-адресу хоста docker. Отspring.datasource.url=jdbc:mysql://mysql:3306/database?
кspring.datasource.url=jdbc:mysql://172.17.0.1:3306/database?
изнутри контейнера Докера, как мне подключиться к localhost машины?
Этот пост также помогает в качестве окончательного решения.
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
...
мой вывод:
Контейнер Дженкинса строит из образа способен взаимодействовать с контейнером MySQL с его именем контейнера или частным адресом в сети моста docker. Однако, поскольку приложение, построенное Дженкинсом, не может этого сделать.
Поскольку порт контейнера MySQL привязан к хост-машине, приложение может взаимодействовать с контейнером MySQL через порт хоста.
если вывод неверен, комментарии приветствуются.
некоторые вещи, которые можно проверить, которые могут помочь вам решить эту проблему.
-
в приложение.свойства попробуйте использовать IP-адрес хоста docker.
С
spring.datasource.url = jdbc:mysql://mysql:3306/DATABASE_URI_PATH
to
spring.datasource.url = jdbc:mysql://192.168.99.100:33060/DATABASE_URI_PATH
Примечание.: Вам нужно будет сопоставить ваш IP и порт, когда вы выполняете docker или порты в файле docker.И используйте ту же сеть docker среди ваших контейнеров.
проверьте, может ли серверное приложение достичь вашего mysql или наоборот. Идти внутри контейнера docker и попробуйте выполнить ping.