数据库连接只要失败一次, 之后就一直失败, 日志打印的错误堆栈都是相同的,一直在"重复"一开始的错误, 即使此时数据库连接已经恢复正常,
导致应用无法连接数据库,除非重启应用才会恢复正常.
这个情况在开发和测试环境都出现过几次, 在本地也可以稳定重现, 重现方式:关闭再开启数据库.
环境:
SpringBoot: 2.0.3.RELEASE, druid-spring-boot-starter: 1.1.10
数据库: MySQL
配置文件:
# DataSource
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://***/***?useUnicode=true&characterEncoding=UTF-8&useSSL=false
spring.datasource.username=***
spring.datasource.password=***
# JPA
spring.jpa.database=MYSQL
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
# Database Connection Pool (Druid)
spring.datasource.druid.initialSize=5
spring.datasource.druid.minIdle=5
spring.datasource.druid.maxActive=20
spring.datasource.druid.maxWait=8000
spring.datasource.druid.breakAfterAcquireFailure=true
spring.datasource.druid.timeBetweenEvictionRunsMillis=60000
spring.datasource.druid.minEvictableIdleTimeMillis=300000
spring.datasource.druid.validationQuery=SELECT 'x'
spring.datasource.druid.testWhileIdle=true
spring.datasource.druid.poolPreparedStatements=true
spring.datasource.druid.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.druid.filters=stat,wall,slf4j
spring.datasource.druid.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
spring.datasource.druid.stat-view-servlet.login-username=***
spring.datasource.druid.stat-view-servlet.login-password=***
8条答案
按热度按时间flmtquvp1#
这个属性我都找不到,换了好几个版本,无线重连直接把服务器干爆了,这问题都没人管管。
1rhkuytd2#
breakAfterAcquireFailure=true导致应用无法连接数据库,除非重启。connectionErrorRetryAttempts默认值1,从源码和自测日志看,应该是失败connectionErrorRetryAttempts+1次(默认2次),就无法连接数据库。源码: DruidDataSource->CreateConnectionThread->run()方法。
dfddblmv3#
druid version:1.1.20
同样发现了这个问题,数据源一直在报connect error。搜了文档也没找到官方介绍这个breakAfterAcquireFailure参数的地方。
再一个有个疑问:Druid在统计建立连接的错误次数后,代码逻辑为什么是在错误次数超过一个阈值(connectionErrorRetryAttempts)的时候就进行继续重连的逻辑?不应该是反过来吗?
fnatzsnv4#
父类DruidAbstractDataSource里倒是有breakxx这个参数的相应setter方法,就调用方法吧。
eqzww0vc5#
所以现在是需要手动检测下状态自己设置breakAfterAcquireFailure值吗?新版本有修复吗
ozxc1zmp6#
2022年了,似乎还是有问题
wribegjk7#
CreateConnectionThread
在设置了breakAfterAcquireFailure=true之后就终止了,只要失败了,这个线程就死掉了,所以getConnection没用
btqmn9zl8#
解决办法也很简单,设置使用自定的scheduler去创建connection就行了: