druid breakAfterAcquireFailure为true时, 数据库连接只要失败一次, 之后就一直失败(即使数据库连接已经恢复正常)

fv2wmkja  于 2022-10-21  发布在  Druid
关注(0)|答案(8)|浏览(316)

数据库连接只要失败一次, 之后就一直失败, 日志打印的错误堆栈都是相同的,一直在"重复"一开始的错误, 即使此时数据库连接已经恢复正常,
导致应用无法连接数据库,除非重启应用才会恢复正常.

这个情况在开发和测试环境都出现过几次, 在本地也可以稳定重现, 重现方式:关闭再开启数据库.

环境:
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=***
flmtquvp

flmtquvp1#

这个属性我都找不到,换了好几个版本,无线重连直接把服务器干爆了,这问题都没人管管。

1rhkuytd

1rhkuytd2#

breakAfterAcquireFailure=true导致应用无法连接数据库,除非重启。connectionErrorRetryAttempts默认值1,从源码和自测日志看,应该是失败connectionErrorRetryAttempts+1次(默认2次),就无法连接数据库。源码: DruidDataSource->CreateConnectionThread->run()方法。

dfddblmv

dfddblmv3#

druid version:1.1.20

同样发现了这个问题,数据源一直在报connect error。搜了文档也没找到官方介绍这个breakAfterAcquireFailure参数的地方。
再一个有个疑问:Druid在统计建立连接的错误次数后,代码逻辑为什么是在错误次数超过一个阈值(connectionErrorRetryAttempts)的时候就进行继续重连的逻辑?不应该是反过来吗?

fnatzsnv

fnatzsnv4#

父类DruidAbstractDataSource里倒是有breakxx这个参数的相应setter方法,就调用方法吧。

eqzww0vc

eqzww0vc5#

所以现在是需要手动检测下状态自己设置breakAfterAcquireFailure值吗?新版本有修复吗

ozxc1zmp

ozxc1zmp6#

2022年了,似乎还是有问题

wribegjk

wribegjk7#

CreateConnectionThread
在设置了breakAfterAcquireFailure=true之后就终止了,只要失败了,这个线程就死掉了,所以getConnection没用

btqmn9zl

btqmn9zl8#

解决办法也很简单,设置使用自定的scheduler去创建connection就行了:

ScheduledExecutorService createScheduler = Executors.newScheduledThreadPool(4);
ScheduledExecutorService destroyScheduler = Executors.newScheduledThreadPool(4);

druidDataSource.setBreakAfterAcquireFailure(true);
druidDataSource.setCreateScheduler(createScheduler);
druidDataSource.setDestroyScheduler(destroyScheduler);

相关问题