简体   繁体   English

Docker-compose 容器连接到 MySql 不起作用

[英]Docker-compose container connection to MySql not working

I'm trying to dockerize an existing java app that uses MySQL database.我正在尝试对使用 MySQL 数据库的现有 java 应用程序进行码头化。

The app is supposed to fill the database upon startup.该应用程序应该在启动时填充数据库。 However, when I try to run the app and the database in docker-compose, the app fails to start up due to not being able to connect to the database.但是,当我尝试在 docker-compose 中运行应用程序和数据库时,由于无法连接到数据库,应用程序无法启动。

When I try to run the docker-compose, after some time I get this error from the app:当我尝试运行 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

This is my docker-compose.yml:这是我的 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

The persistence.xml:持久性.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" />
...

I can connect from the host machine to the dockerized database correctly.我可以正确地从主机连接到 dockerized 数据库。

Did I get my configuration wrong?我是不是配置错了? Also, is there any way to debug the db connection from the app container?另外,有没有办法从应用容器调试数据库连接?

You should change JDBC url to:您应该将 JDBC url 更改为:

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

Docker-compose connects containers to the default network and service name is the DNS name which will be mapped to container IP. Docker-compose 将容器连接到默认网络,服务名称是 DNS 名称,它将映射到容器 IP。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM