Spring Boot JPA - 配置自动重新连接

sto*_*fer 102 configuration spring spring-boot

我有一个很好的小Spring Boot JPA Web应用程序.它部署在Amazon Beanstalk上,并使用Amazon RDS来保存数据.然而,经常使用它并因此在一段时间后因此类异常而失败:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:从服务器成功收到的最后一个数据包是79,870,633毫秒.
成功发送到服务器的最后一个数据包是79,870,634毫秒.比服务器配置的'wait_timeout'值长.您应该考虑在应用程序中使用之前过期和/或测试连接有效性,增加服务器配置的客户端超时值,或使用Connector/J连接属性"autoReconnect = true"来避免此问题.

我不知道如何配置此设置,但无法在http://spring.io上找到相关信息(虽然这是一个非常好的网站).有哪些想法或信息指针?

Ste*_*oll 133

我假设启动正在DataSource为您配置.在这种情况下,由于您使用的是MySQL,因此可以将以下内容添加到application.properties最多1.3

spring.datasource.testOnBorrow=true
spring.datasource.validationQuery=SELECT 1
Run Code Online (Sandbox Code Playgroud)

如djxak在注释所指出的,1.4+定义了特定的命名空间的四个连接池弹簧Boot支持:tomcat,hikari,dbcp,dbcp2(dbcp被弃用的1.5).您需要检查您正在使用的连接池,并检查是否支持该功能.以上示例适用于tomcat,因此您必须在1.4+中按如下方式编写它:

spring.datasource.tomcat.testOnBorrow=true 
spring.datasource.tomcat.validationQuery=SELECT 1
Run Code Online (Sandbox Code Playgroud)

请注意,使用的autoReconnect不建议:

建议不要使用此功能,因为当应用程序无法正确处理SQLExceptions时,它会产生与会话状态和数据一致性相关的副作用,并且仅在您无法配置应用程序以处理由此产生的SQLExceptions时使用.死和陈旧的连接正确.

  • 因为它可能会混淆其他人:`SELECT 1`保证连接在交给应用程序之前已经过测试.通过使用`testOnBorrow = true`,对象将在从池中借用之前进行验证.如果对象无法验证,它将从池中删除,并将尝试借用另一个.注 - 要使true值生效,必须将validationQuery参数设置为非空字符串. (14认同)
  • **警告!**在Spring Boot 1.4+中,这已经[更改](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.4-Release-Notes#datasource-binding):为spring支持的四个连接池定义了新的特定命名空间:`tomcat`,`hikari`,`dbcp`,`dbcp2`.因此,例如,对于`tomcat-jdbc`连接池,属性应为:`spring.datasource.tomcat.testOnBorrow = true`和`spring.datasource.tomcat.validationQuery = SELECT 1`. (14认同)
  • 那是因为我们统一了我们在文档中编写密钥的方式.我们总是使用_relaxed_ binder,因此`spring.datasource.testOnBorrow`和`spring.datasource.test-on-borrow`都可以正常工作.有关详细信息,请查看[文档](http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config-relaxed-binding). (7认同)
  • 如果我自己配置​​两个不同的数据源,那么我如何提供这些配置?我是否需要为 spring.datasource.mydatasource1.tomcat.testOnBorrow=true 这样的数据源提供此配置 spring.datasource.mydatasource1.tomcat.validationQuery=SELECT 1 spring.datasource.mydatasource2.tomcat.testOnBorrow=true spring.datasource。 mydatasource2.tomcat.validationQuery=SELECT 1 或者还有其他要遵循的事情? (2认同)
  • **警告!**如果您在应用中定义了任何DataSource @Bean,那么Spring Boot不会*配置池。https://docs.spring.io/spring-boot/docs/1.5.16.RELEASE/reference/htmlsingle/#boot-features-connect-to-production-database`如果定义了自己的DataSource bean,则会自动配置不会发生。`我遵循了OAuth2的指南,并使用了@Bean(name =“ OAuth”)public DataSource secondaryDataSource()...,它没有自动配置,也未使用`testOnBorrow`。 (2认同)
  • 如果您使用的是 hikari(Spring Boot 2 中的默认连接池),则无需像 hikari 那样在将连接交给您之前对其进行测试。引用自 [HikariCP github 页面](https://github.com/brettwooldridge/HikariCP):`...Connection.isValid() API。这是在从池中向您提供连接之前执行的查询,以验证与数据库的连接是否仍然有效。 (2认同)

Sou*_*mya 27

以上建议对我不起作用.真正有效的是在application.properties中包含以下行

spring.datasource.testWhileIdle = true
spring.datasource.timeBetweenEvictionRunsMillis = 3600000
spring.datasource.validationQuery = SELECT 1
Run Code Online (Sandbox Code Playgroud)

你可以在这里找到解释

  • 您添加的链接显示**如果数据库连接处于非活动状态超过8个小时,它将自动关闭,并且会发生上述错误。**因此,您的解决方案是不要让连接保持较长时间的非活动状态。重新启动后,有什么方法可以连接到SQL Server吗? (3认同)

Jos*_*ado 8

我刚刚转到Spring Boot 1.4,发现这些属性已重命名:

spring.datasource.dbcp.test-while-idle=true
spring.datasource.dbcp.time-between-eviction-runs-millis=3600000
spring.datasource.dbcp.validation-query=SELECT 1
Run Code Online (Sandbox Code Playgroud)

  • 名称是等效的。请参阅[Spring Boot docs](http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-外部配置松弛绑定)。 (2认同)

who*_*ami 8

spring.datasource.tomcat.testOnBorrow=trueapplication.properties中的设置不起作用.

以编程方式设置如下工作没有任何问题.

import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;    

@Bean
public DataSource dataSource() {
    PoolProperties poolProperties = new PoolProperties();
    poolProperties.setUrl(this.properties.getDatabase().getUrl());         
    poolProperties.setUsername(this.properties.getDatabase().getUsername());            
    poolProperties.setPassword(this.properties.getDatabase().getPassword());

    //here it is
    poolProperties.setTestOnBorrow(true);
    poolProperties.setValidationQuery("SELECT 1");

    return new DataSource(poolProperties);
}
Run Code Online (Sandbox Code Playgroud)