Spring 2.7.2中DataSource Bean未读取Hikari配置致连接超时告警
问题:Hikari连接池持续抛出连接失效警告,配置未生效
我使用Spring 2.7.2,运行一段时间后执行数据库操作时,持续收到如下WARN日志:
HikariPool-1 - Failed to validate connection com.mysql.cj.jdbc.ConnectionImpl@ (No operations allowed after connection closed.). Possibly consider using a shorter maxLifetime value.
我已经将max-lifetime: 140000设为更小的值,但警告依然存在。通过数据库查询show global variables like '%wait_timeout%';得到wait_timeout为10分钟(单位秒),而我的配置是140000毫秒(2分20秒),理论上不应该出现告警。
因为这是我首次手动创建DataSource Bean,我猜测这个Bean仍在使用max-lifetime的默认值(Hikari文档显示默认值为1800000毫秒即30分钟,远大于数据库的wait_timeout),没有读取yml中的配置。
我的DataSource Bean代码如下:
import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class DataSourceConfig { @Bean @Qualifier("datasource") public DataSource getDataSource(final @Value("${spring.datasource.host}") String host, final @Value("${spring.datasource.username}") String user, final @Value("${spring.datasource.password}") String password) throws DecrypterException { return DataSourceBuilder.create().url(String.format( "jdbc:mysql://%s/%s?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&useSSL=false", decrypter.getEnv(host), "databasename")).username(user).password(decrypter.getEnv(password)).build(); } }
由于host和密码是加密的环境变量,需要通过特定库解密,所以必须手动创建Bean。我的application.yml配置如下:
spring: datasource: host: ENCRYPTED_HOST username: normal_user password: ENCRYPTED_PASSWORD driverClassName: com.mysql.cj.jdbc.Driver hikari: maximum-pool-size: 65 max-lifetime: 140000 jpa: open-in-view: false show-sql: false
我是否遗漏了配置?这个Bean是不是无法读取yml中的配置?是否需要在Bean中手动配置Hikari参数(如下示例)?如果需要,如何在保留默认配置的前提下修改指定参数?
HikariConfig config = new HikariConfig(); config.setMaxLifetime(140000); config.setMaximumPoolSize(65); HikariDataSource source = new HikariDataSource(config); DataSourceBuilder builder = DataSourceBuilder.create(); builder.derivedFrom(source);
内容的提问来源于stack exchange,提问作者BugsOverflow
相关产品推荐
相关产品推荐

