Druid連接池參數maxWait配置錯誤引發的問題
Druid連接池參數maxWait配置錯誤引發的問題
1. 背景
資料庫伺服器(服務部署在客戶內網環境)的運行一段時間後,網卡出現了問題,導致所有服務都連接不上資料庫,客戶把網路恢復之後,回饋有個服務還是訪問異常。
2.問題定位
查看異常服務的日誌,發現當時的日誌列印出了大量的Too many open files,日誌表明當時該進程打開的文件句柄數已達到上限,該進程已經不能自動恢復對資料庫的訪問。
通過命令ulimit -a查看配置,確認伺服器配置沒有問題。
使用jstack命令查看當時執行緒的資訊,發現大量獲取資料庫連接的執行緒處於BLOCKED狀態。
從執行緒堆棧資訊發現,執行緒是從Druid連接池獲取連接的,於是查看DruidDataSource獲取連接的方法,發現有個maxWait參數(默認配置為-1)
查看項目的配置文件,發現有配置spring.datasource.maxWait=60000
通過debug的方式發現改配置沒有生效
3.原因分析
項目是通過spring.datasource.type=com.alibaba.druid.pool.DruidDataSource引入druid連接池,通過這種方式引入配置文件中的其他屬性是無法自動注入。要使該配置生效,可使用javaBean的方式配置。
@Configuration
public class DruidConfig {
@Bean
// 將所有前綴為spring.datasource下的配置項都載入DataSource中
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druidDataSource() {
return new DruidDataSource();
}
}
關於maxWait的默認值,即如果連接池沒有空閑連接,獲取連接的執行緒則會一直等待下去。在項目中,在後台有個按時觸發統計的定時任務,定時的向連接池獲取連接,即每個固定時間間隔內就會有一個執行緒阻塞。資料庫宕機時間一長就會導致,該進程打開的句柄數超過上限。
關於spring.datasource前綴沒有自動注入的原因,可以自行查看springboot 數據源自動注入DataSourceAutoConfiguration類