可怕的 Java Spring Boot 应用程序未使用 Docker-compose java.net.ConnectException 连接到 MySQL:连接被拒绝

Posted

技术标签:

【中文标题】可怕的 Java Spring Boot 应用程序未使用 Docker-compose java.net.ConnectException 连接到 MySQL:连接被拒绝【英文标题】:The dreaded Java SpringBoot app not connecting to MySQL with Docker-compose java.net.ConnectException: Connection refused 【发布时间】:2021-02-23 09:38:50 【问题描述】:

我一直在努力解决以下问题 - 可怕的 Java SpringBoot 应用程序无法连接到 mysql 并出现 docker compose 异常:

com.mysql.cj.jdbc.exceptions.CommunicationsException:通信链路故障

JDBCConnectionException:无法打开 JDBC 连接以执行 DDL

java.net.ConnectException:连接被拒绝

该应用程序本身运行良好,但是一旦我在 Docker 中获得它,它似乎无法连接到 mysql。我想我的所有参数都是正确的,我错过了什么?

平台:
MacOS Mojave 10.14.6
---
Docker version 19.03.13, build 4484c46d9d
docker-compose version 1.27.4, build 40524192
---
mysql  Ver 8.0.21 for osx10.14 on x86_64 (Homebrew)
---
openjdk 11.0.8 2020-07-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.8+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.8+10, mixed mode)
---
Spring CLI v2.3.4.RELEASE
---
Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-17T21:33:14+03:00)
Maven home: /usr/local/Cellar/maven@3.5/3.5.4_1/libexec
Java version: 11.0.8, vendor: AdoptOpenJDK, runtime: /Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home
Default locale: en_GB, platform encoding: UTF-8
OS name: "mac os x", version: "10.14.6", arch: "x86_64", family: "mac"

这是整个代码库:Codebase

使用命令运行:

docker-compose up --build --remove-orphans

我的 docker-compose.yml(注释掉的东西是我试过的东西):

version: "3.8"
services:
  genesysmysql:
    container_name: genesysmysql
#    container_name: genesysmysql_container
    image: "mysql:8.0.21"
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=db_example
      - MYSQL_USER=springuser
      - MYSQL_PASSWORD=ThePassword
    ports:
      - 3306:3306
    volumes:
      - ./setup.sql:/docker-entrypoint-initdb.d/setup.sql:ro
    healthcheck:
      test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
      timeout: 20s
      retries: 20
  genesys:
    build: .
    ports:
      - 8080:8080
    depends_on:
      genesysmysql:
        condition: service_healthy
    environment:
      - spring.datasource.jdbc-url=jdbc:genesysmysql://db_example:3306?useSSL=false&allowPublicKeyRetrieval=true&autoReconnect=true
#      - spring.datasource.jdbc-url=jdbc:genesysmysql://db_example:3306?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC&autoReconnect=true
      - spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#      - spring.datasource.username=root
#      - spring.datasource.password=root
#      - spring.datasource.username=springuser
#      - spring.datasource.password=ThePassword
#      - spring.jpa.hibernate.ddl-auto=create-drop
      - spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
#      - spring.data.jpa.repositories.enabled=true
#      - spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
#      - spring.jpa.generate-ddl=true

我的 setup.sql 脚本:

CREATE DATABASE db_example;
CREATE USER 'springuser'@'%' IDENTIFIED BY 'ThePassword';
GRANT ALL ON db_example.* to 'springuser'@'%';
GRANT ALL ON db_example.* TO 'springuser'@'localhost';
GRANT ALL ON db_example.* TO 'springuser'@'genesysmysql_container';
GRANT ALL ON db_example.* TO 'springuser'@'genesysmysql';

我的码头文件:

FROM adoptopenjdk/openjdk11:alpine
MAINTAINER  atkuzmanov <https://github.com/atkuzmanov>
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring
ARG JAR_FILE=target/*.jar
COPY $JAR_FILE app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]

我的 application.properties 文件:

### Spring properties
spring.application.name=@project.name@
#spring.output.ansi.console-available=true
#server.port=8080
spring.output.ansi.enabled=ALWAYS

### Spring banner properties
#spring.banner.location=classpath:banner.txt
#spring.main.banner-mode=off
info.app.name=@project.name@
info.app.version=@project.version@
info.app.url=@project.url@

### Spring Actuator properties
## Do not expose or enable the 'shutdown' option in a public production application.
#management.endpoint.shutdown.enabled=true
management.endpoints.web.exposure.include=health,info,httptrace

### Spring Devtools properties
#spring.devtools.add-properties=false
#spring.devtools.restart.log-condition-evaluation-delta=false
#spring.devtools.restart.enabled=false
#spring.devtools.livereload.enabled=false

### Spring logging properties
## Change logging levels as appropriate when debugging
logging.level.=WARN
logging.level.customLogbackLevel=INFO
logging.level.org.springframework=WARN
logging.level.org.springframework.web.servlet.=ERROR
logging.level.org.hibernate=ERROR
logging.level.org.apache.catalina.core.ContainerBase.=WARN

### Spring Distributed Tracing properties
## Zipkin properties
spring.zipkin.enabled=true
spring.zipkin.base-url=http://127.0.0.1:9411/
## Sleuth properties
spring.sleuth.enabled=true
spring.sleuth.sampler.percentage=0.5
#spring.sleuth.web.skipPattern=(^cleanup.*|.+favicon.*)

### Spring Data properties
## These are just to get things started, should be changed afterwards.
#spring.jpa.hibernate.ddl-auto=none
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://$MYSQL_HOST:localhost:3306/db_example?useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.username=springuser
spring.datasource.password=ThePassword
#spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5

### Spring Open Session properties
### Warning message by default:
## "spring.jpa.open-in-view is enabled by default.
## Therefore, database queries may be performed during view rendering.
## Explicitly configure spring.jpa.open-in-view to disable this warning"
## See:
## RE: spring.jpa.open-in-view Warning
## - <https://***.com/questions/30549489/what-is-this-spring-jpa-open-in-view-true-property-in-spring-boot>
## - <https://www.baeldung.com/spring-open-session-in-view>
spring.jpa.open-in-view=true

### Spring Thymeleaf properties
spring.thymeleaf.cache=false

以下是异常消息:

例外 1: Exception 1

概念 2: Exception 2

例外 3: Exception 3

Exception 4,它封装了所有这些: Exception 4


  "app": "GeneSys",
  "logMsgId": "f7b6c3cc-0dce-4eb6-b6c3-cc0dce1eb69c",
  "@timestamp": "2020-11-11T11:20:31.822Z",
  "@version": "1",
  "logger": "org.springframework.boot.SpringApplication",
  "level": "ERROR",
  "thread": "main",
  "stackTrace": "org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'timestampRepository' defined in com.atkuzmanov.genesys.dao.TimestampRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Cannot resolve reference to bean 'jpaMappingContext' while setting bean property 'mappingContext'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:342)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:113)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1697)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1442)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:624)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:612)
    at org.springframework.data.repository.config.DeferredRepositoryInitializationListener.onApplicationEvent(DeferredRepositoryInitializationListener.java:51)
    at org.springframework.data.repository.config.DeferredRepositoryInitializationListener.onApplicationEvent(DeferredRepositoryInitializationListener.java:36)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:404)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:361)
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:898)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:554)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
    at com.atkuzmanov.genesys.GenesysApplication.main(GenesysApplication.java:15)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:107)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
    at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1794)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:330)
    ... 36 common frames omitted
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:403)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:112)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
    at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:69)
    at org.hibernate.tool.schema.internal.exec.ImprovedExtractionContextImpl.getJdbcConnection(ImprovedExtractionContextImpl.java:60)
    at org.hibernate.tool.schema.internal.exec.ImprovedExtractionContextImpl.getJdbcDatabaseMetaData(ImprovedExtractionContextImpl.java:67)
    at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.getTables(InformationExtractorJdbcDatabaseMetaDataImpl.java:333)
    at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.getTablesInformation(DatabaseInformationImpl.java:120)
    at org.hibernate.tool.schema.internal.GroupedSchemaMigratorImpl.performTablesMigration(GroupedSchemaMigratorImpl.java:65)
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.performMigration(AbstractSchemaMigrator.java:207)
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:114)
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:184)
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:73)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:316)
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:469)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1259)
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:391)
    ... 4 common frames omitted
Caused by: com.mysql.cj.jdbc.exceptions.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 com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174)
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64)
    at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:836)
    at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:456)
    at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246)
    at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:197)
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:358)
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:477)
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:560)
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
    at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
    at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:180)
    at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:43)
    ... 19 common frames omitted
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: 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 java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    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.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
    at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
    at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151)
    at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167)
    at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:91)
    at com.mysql.cj.NativeSession.connect(NativeSession.java:144)
    at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:956)
    at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:826)
    ... 32 common frames omitted
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:609)
    at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:155)
    at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:65)
    ... 35 common frames omitted
",
  "message": "Application run failed",
  "method": "reportFailure",
  "class": "org.springframework.boot.SpringApplication"

【问题讨论】:

docker里面的localhost很无聊。在端口中映射或使用 MySQL 容器的名称。 @ThorbjørnRavnAndersen,谢谢,我不确定我是否理解正确。我在 docker-compose: environment: - spring.datasource.jdbc-url=jdbc:genesysmysql://db_example:3306?useSSL=false&amp;allowPublicKeyRetrieval=true&amp;autoReconnect=true 中覆盖它,并且我已将 genesysmysql 设置为容器名称。我应该改变什么? 【参考方案1】:

要修复它,您只需将参数 spring.datasource.jdbc-url 更改为 spring.datasource.url 并将连接字符串更改为 jdbc:mysql: //genesysmysql:3306/db_example?useSSL=false&allowPublicKeyRetrieval=true&autoReconnect=true。您的连接字符串有错误。

【讨论】:

您先生,完全正确,这已解决,非常感谢您!我想我看了很久,错过了。现在我收到的唯一消息是应用程序启动时genesysmysql | mbind: Operation not permitted,知道为什么吗? @atkuzmanov 试试看这里***.com/questions/55559386/… cap_add: - SYS_NICE # CAP_SYS_NICE 成功了,再次感谢您! ( :

以上是关于可怕的 Java Spring Boot 应用程序未使用 Docker-compose java.net.ConnectException 连接到 MySQL:连接被拒绝的主要内容,如果未能解决你的问题,请参考以下文章

架构实战篇(十三):Spring Boot Logback 邮件通知

Spring Boot . 2 -- 用Spring Boot 创建一个Java Web 应用

Spring Boot 应用程序 - 启动时间与“mvn spring-boot:run”和“java -jar”的差异

如何 JUnit 测试 Spring-Boot 的 Application.java

软帝学院Spring Boot 是什么?为什么说java程序员必须要掌握Spring Boot ?

Java进阶之Spring Boot