【问题标题】:How to solve "Communications link failure" problem on a Spring Boot Application using mysql?如何使用 mysql 解决 Spring Boot 应用程序上的“通信链接失败”问题?
【发布时间】:2020-04-22 16:53:27
【问题描述】:

我基于 Heroku 的"Getting Started on Heroku with Java" 开发了一个 Spring Boot 应用程序。之后,我开始将 mysql 配置为数据库。 This 是我在整个方法中遵循的教程。当我使用 heroku local web 在本地运行应用程序时,一切正常。我可以发出 GET 请求并获取存储在数据库中的数据。我可以发出 POST 请求并将新数据添加到数据库中。但是如果我将它部署到生产环境中,我会在日志中看到异常。以下是我在启动运行在 Heroku 提供给我的 url 上的应用程序时看到的日志的相关部分,在本例中为:https://danef-dictionary-api.herokuapp.com/

com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
Jan 04 02:24:27 danef-dictionary-api app/web.1 
Jan 04 02:24:27 danef-dictionary-api app/web.1 The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
Jan 04 02:24:27 danef-dictionary-api app/web.1  at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174) ~[mysql-connector-java-8.0.18.jar:8.0.18]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64) ~[mysql-connector-java-8.0.18.jar:8.0.18]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:836) ~[mysql-connector-java-8.0.18.jar:8.0.18]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:456) ~[mysql-connector-java-8.0.18.jar:8.0.18]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246) ~[mysql-connector-java-8.0.18.jar:8.0.18]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:199) ~[mysql-connector-java-8.0.18.jar:8.0.18]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) ~[HikariCP-3.4.1.jar:na]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:353) ~[HikariCP-3.4.1.jar:na]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) ~[HikariCP-3.4.1.jar:na]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:473) [HikariCP-3.4.1.jar:na]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:562) [HikariCP-3.4.1.jar:na]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115) [HikariCP-3.4.1.jar:na]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) [HikariCP-3.4.1.jar:na]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) [hibernate-core-5.4.9.Final.jar:5.4.9.Final]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:180) [hibernate-core-5.4.9.Final.jar:5.4.9.Final]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:68) [hibernate-core-5.4.9.Final.jar:5.4.9.Final]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35) [hibernate-core-5.4.9.Final.jar:5.4.9.Final]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101) [hibernate-core-5.4.9.Final.jar:5.4.9.Final]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263) [hibernate-core-5.4.9.Final.jar:5.4.9.Final]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237) [hibernate-core-5.4.9.Final.jar:5.4.9.Final]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214) [hibernate-core-5.4.9.Final.jar:5.4.9.Final]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152) [hibernate-core-5.4.9.Final.jar:5.4.9.Final]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286) [hibernate-core-5.4.9.Final.jar:5.4.9.Final]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243) [hibernate-core-5.4.9.Final.jar:5.4.9.Final]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214) [hibernate-core-5.4.9.Final.jar:5.4.9.Final]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:175) [hibernate-core-5.4.9.Final.jar:5.4.9.Final]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:118) [hibernate-core-5.4.9.Final.jar:5.4.9.Final]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1202) [hibernate-core-5.4.9.Final.jar:5.4.9.Final]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1233) [hibernate-core-5.4.9.Final.jar:5.4.9.Final]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) [spring-orm-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) [spring-orm-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:391) [spring-orm-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:378) [spring-orm-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) [spring-orm-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1855) [spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1792) [spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595) [spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) [spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) [spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) [spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) [spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1108) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
Jan 04 02:24:27 danef-dictionary-api app/web.1  at net.danef.DanefDictionaryApiApplication.main(DanefDictionaryApiApplication.java:12) ~[classes/:na]

从例外中,我选择了第一个,“公共链接故障”,并在这个问题的标题中使用了它。我可能已经尝试了所有我能找到的解决方案,所以如果您知道博客文章或您认为有帮助的答案,请随时重定向我。

我的 application.properties 文件:

spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.jpa.generate-ddl=true
spring.datasource.url=jdbc:mysql://localhost:3306/db_words?useSSL=false
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=myusername
spring.datasource.password=mypassword

“myusername”和“mypassword”只是占位符。我在我的代码上使用我的凭据。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>net.danef</groupId>
    <artifactId>danef-dictionary-api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>danef-dictionary-api</name>
    <description>Danef Dictionary API</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>3.0.1</version>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

如果您想查看完整版日志,请参考此链接:https://paste.ubuntu.com/p/wqZPXqyYFM/

【问题讨论】:

  • @mangusta 没问题,是的。
  • @mangusta 在代码方面没有什么可做的。真的吗?我试过从另一个网络连接,它是一样的。所以我不会给太多机会。有没有办法可以确定是防火墙还是其他阻止了连接的东西?
  • 您是否使用jdbc:mysql://localhost:3306/db_words 作为您的数据库 url 从生产中连接?如果是,那么它无法连接也就不足为奇了(除非 DB 与生产服务器位于同一主机上)。
  • 是的。这也是我在生产中使用的 URL。我试过设置一个不同的。它有确切的数字而不是本地主机。但我无法让它工作。我需要使用的 URL 是什么?
  • 如果您的数据库服务器有一个公共 IP 地址(这 4 个数字由点分隔),请将原始 URL 中的 localhost 替换为该数字:spring.datasource.url=jdbc:mysql://xxx.xxx.xxx.xxx:3306/db_words?useSSL=false

标签: java mysql spring spring-boot heroku


【解决方案1】:

我通过在 Heroku 中设置 ClearDB 插件解决了我的问题。添加插件后,我有了一个远程数据库 URL。将远程 URL 设置为 datasource.url 解决了这个问题。我的 application.properties 文件现在看起来像这样。

spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.jpa.generate-ddl=true
spring.datasource.url=jdbc:mysql://`remote_database_url`
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=samet
spring.datasource.password=password

设置不带反引号的远程数据库 URL。

【讨论】:

  • 您应该使用$JDBC_DATABASE_URL$SPRING_DATASOURCE_URL,而不是对JDBC URL 进行硬编码
  • 好的。我需要在哪里申报?
【解决方案2】:

当我们工作在container(spring app)到container(mysql)的通信模式时。

  • 在 application.yml 或 properties 中添加 mysql 容器名称在 url,例如: jdbc:mysql://&lt;container_name&gt;:3306/movie_rest_service
  • 端口很重要:mysql会在3306等待,即使你在mysql运行中提到其他端口,例如: docker run --name mysqldb -d -p 3307:3307 -e MYSQL_ROOT_PASSWORD=Mysql123 -e MYSQL_DATABASE=movie_rest_service -e MYSQL_USER=user1 -e MYSQL_PASSWORD=Mysql123 project/mysql
  • 通过禁用测试构建 App jar。
  • 运行Mysql镜像
  • 运行App镜像,例如: docker run -t --link &lt;mysql_container_name&gt;:mysql -p 8080:8080 &lt;app image name&gt;

【讨论】:

    【解决方案3】:

    我们的 java 应用部署在 Kubernetes pod(容器)中

    我遇到了这个问题,当我们将 application.yml 文件中的驱动程序从 jdbc:mysql 更改为 jdbc:mariadb 时,它得到了解决。

    【讨论】:

      【解决方案4】:

      就我而言,我不得不更改 mysql 配置文件

      /etc/mysql/my.cnf
      

      我换行了:

      bind-address = 127.0.0.1
      

      bind-address = ::
      

      如果绑定地址是 ::,则服务器接受所有服务器主机 IPv4 和 IPv6 接口上的 TCP/IP 连接。使用此地址允许所有服务器接口上的 IPv4 和 IPv6 连接。

      【讨论】:

        【解决方案5】:

        如果您使用 docker-compose 来创建您的数据库和另一个 docker-compose 到您的应用程序,您需要使用您提供的服务名称...
        假设 docker-db.yml 是:

        version: "3"
        services:
          vehicles-dbserver:
            image: mysql:latest
            ports:
              - 3306:3306
            environment:
              - MYSQL_ROOT_PASSOWRD=root123
              - MYSQL_USER=user
              - MYSQL_PASSWORD=user123
            volumes:
              - /opt/mysql-data:/var/lib/mysql
            networks:
              - application
        networks:
          application:
        

        docker-app.yml 应该是:

        version: "3"
        services:
          vehicles-api:
            image: application/vehicles
            ports:
              - 8080:8080
            environment:
              - DATABASE_USER=user
              - DATABASE_PASSWORD=user123
              - DATABASE_URL=jdbc:mysql://vehicles-dbserver:3306/vehicles-database?useSSL=false&useLegacyDatetimeCode=false&allowPublicKeyRetrieval=true
              - DATABASE_DRIVER=com.mysql.cj.jdbc.Driver
            networks:
              - application
        networks:
          application:
        

        注意点是“DATABASE_URL=jdbc:mysql://vehicles-dbserver:3306”

        【讨论】:

          【解决方案6】:

          如果您确定 ide、驱动程序、mysql 等的所有版本仍然无法正常工作,请前往 ide 检查 java 版本及其供应商。我更喜欢 oracle 和 opejdk java vendor。

          我遇到了同样的错误,我无法理解为什么这个错误,而所有设置都是正确的,我检查了 java 版本和它的供应商。改了之后就可以了。

          【讨论】:

            猜你喜欢
            • 2019-06-21
            • 2019-06-06
            • 1970-01-01
            • 2021-01-12
            • 2020-10-21
            • 2020-04-05
            • 2019-10-20
            • 2019-07-07
            • 2019-07-04
            相关资源
            最近更新 更多