Druid連線池引數maxWait配置錯誤引發的問題

quansheng發表於2022-01-08

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類

相關文章