Не удалось получить соединение 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 на плагин базы данных. Соединение Успешно!

enter image description here

параметр подключения в 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.