【问题标题】:Docker-compose container connection to MySql not workingDocker-compose 与 MySql 的容器连接不起作用
【发布时间】:2020-02-13 14:13:00
【问题描述】:

我正在尝试对使用 MySQL 数据库的现有 java 应用程序进行 dockerize。

应用程序应该在启动时填充数据库。但是,当我尝试在 docker-compose 中运行应用程序和数据库时,由于无法连接到数据库,应用程序无法启动。

当我尝试运行 docker-compose 时,一段时间后我从应用程序中收到此错误:

16-Oct-2019 17:28:53.724 INFO [main] com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource. Initializing c3p0 pool... com.mchange.v2.c3p0.PoolBackedDataSource@25010be1 [ connectionPoolDataSource -> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@66bb20d8 [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, debugUnreturnedConnectionStackTraces -> false, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, identityToken -> 1bqsumba51n9qs60y7txqe|66f4fb48, idleConnectionTestPeriod -> 300, initialPoolSize -> 5, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 300, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 20, maxStatements -> 50, maxStatementsPerConnection -> 0, minPoolSize -> 5, nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@2252819d [ description -> null, driverClass -> null, factoryClassLocation -> null, forceUseNamedDriverClass -> false, identityToken -> 1bqsumba51n9qs60y7txqe|3dc238ae, jdbcUrl -> jdbc:mysql://localhost:3306/db-name, properties -> {password=******, useUnicode=true, handling_mode=DELAYED_ACQUISITION_AND_HOLD, characterEncoding=UTF-8, user=******} ], preferredTestQuery -> null, privilegeSpawnedThreads -> false, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false; userOverrides: {} ], dataSourceName -> null, extensions -> {}, factoryClassLocation -> null, identityToken -> 1bqsumba51n9qs60y7txqe|27551c3a, numHelperThreads -> 3 ]

16-Oct-2019 17:29:24.014 WARNING [C3P0PooledConnectionPoolManager[identityToken->1bqsumba51n9qs60y7txqe|27551c3a]-HelperThread-#1] com.mchange.v2.resourcepool.BasicResourcePool. com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@7a309de0 -- Acquisition Attempt Failed!!! Clearing pending acquires. While trying to acquire a needed new resource, we failed to succeed more than the maximum number of allowed acquisition attempts (30). Last acquisition attempt exception:
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.
    at jdk.internal.reflect.GeneratedConstructorAccessor29.newInstance(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:377)
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1036)
    at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:338)
    at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2232)
    at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2265)
    at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2064)
    at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:790)
    at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:44)
    at jdk.internal.reflect.GeneratedConstructorAccessor26.newInstance(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:377)
    at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:395)
    at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:325)
    at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:175)
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:220)
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:206)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:203)
    at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1138)
    at com.mchange.v2.resourcepool.BasicResourcePool.doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess(BasicResourcePool.java:1125)
    at com.mchange.v2.resourcepool.BasicResourcePool.access$700(BasicResourcePool.java:44)
    at com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run(BasicResourcePool.java:1870)
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:696)
Caused by: java.net.ConnectException: Connection refused (Connection refused)
    at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)
    at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)
    at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)
    at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:403)
    at java.base/java.net.Socket.connect(Socket.java:591)
    at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:213)
    at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:297)
    ... 20 more

这是我的 docker-compose.yml:

version: "2.1"

services:
  app:
    build: .
    expose:
      - 8080
    ports:
      - 8080:8080
    links:
      - database
    depends_on:
      database:
        # waits for database to be ready
        condition: service_healthy

  database:
    image: mysql:latest
    command: --default-authentication-plugin=mysql_native_password
    security_opt:
      - seccomp:unconfined
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=db-name
      - MYSQL_USER=user-web
      - MYSQL_PASSWORD=pass
    expose:
      - 3306
    ports:
      - 3306:3306
    healthcheck:
      # checks whether database is ready
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
      timeout: 20s
      retries: 10

persistence.xml:

...
<!-- JDBC Connection configuration -->
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.password" value="pass"/>
<property name="javax.persistence.jdbc.user" value="user-web"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/db-name"/>
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding" value="UTF-8" />
...

我可以正确地从主机连接到 dockerized 数据库。

我的配置有误吗?另外,有没有办法从应用容器调试数据库连接?

【问题讨论】:

  • JDBC url 应该是jdbc:mysql://database:3306/db-name

标签: java mysql docker docker-compose


【解决方案1】:

您应该将 JDBC url 更改为:

<property name="javax.persistence.jdbc.url" value="jdbc:mysql://database:3306/db-name"/>

Docker-compose 将容器连接到默认网络,服务名称是将映射到容器 IP 的 DNS 名称。

【讨论】:

  • 谢谢,这似乎有效!但是,有没有办法保持 persistence.xml 原样并仅修改 docker 端的设置?
  • 我不确定您使用的是什么堆栈(Java EE、Hibernate、Spring)?通常,您将为容器提供一个环境变量,它可以覆盖该属性。或者您可以仅将修改后的 persistence.xml 复制到图像/容器中。以this 为例。
猜你喜欢
  • 2019-04-14
  • 1970-01-01
  • 2022-06-26
  • 2018-11-03
  • 2019-04-24
  • 2020-09-18
  • 2020-07-10
  • 1970-01-01
  • 2018-10-23
相关资源
最近更新 更多