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類

Tags: