alibaba / druid

阿里云计算平台DataWorks(https://help.aliyun.com/document_detail/137663.html) 团队出品,为监控而生的数据库连接池
https://github.com/alibaba/druid/wiki
Apache License 2.0
27.76k stars 8.55k forks source link

为使长期不使用的连接被释放掉,开启removeAbandoned时,一个连接使用超过设定的超时时间时,但还在使用中,连接被关闭,导致业务受损 #5989

Closed Mrwanghappytime closed 2 weeks ago

Mrwanghappytime commented 2 weeks ago

dbtype:mysql dbversion:5.7 druid verion:1.2.22 error sql:no *testcase code: @Bean public DataSource dataSource() { DruidDataSource druidDataSource = new DruidDataSource(); // 省略url和username,password,driver,max等配置 druidDataSource.setRemoveAbandoned(true); druidDataSource.setLogAbandoned(true); druidDataSource.setRemoveAbandonedTimeoutMillis(120 1000); return druidDataSource; } stacktrace info:

error info: abandon connection, owner thread:xxx connected at

为使长期不使用的连接被释放掉,开启removeAbandoned时,一个连接使用超过设定的超时时间时,但还在使用中,连接被关闭,导致业务受损

Mrwanghappytime commented 2 weeks ago

image image 感觉此处应该取上次连接的活跃时间,而不是建立连接的时间,这样长任务会失败,导致业务受损

lizongbo commented 2 weeks ago

你的用法不正确,removeAbandoned主要是用来找出那些连接借出去然后没有执行close进行归还的场景,方便在测试环境发现连接泄露问题并进行处理,在生产环境并不建议开启removeAbandoned。

且连接执行一个耗时很久的sql时,socket层也不会数据返回,也不会走到执行这个afterExcute方法的逻辑,因此调整这个时间也没有用。

参考我更新之后的wiki,即使要开启removeAbandoned,removeAbandonedTimeoutMillis建议设置也最好是一个小时以上。

https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%88%97%E8%A1%A8

lizongbo commented 2 weeks ago

真要关闭长期不使用的连接的话,minIdle配置成0就可以了。