SingleDataSource 對應 GroupDataSource 主庫節點 或一個從庫節點
由于它是對應的是實際的db節點,直接和底層數據庫連接池打交道; zebra 將它的生命周期交由 SingleDataSourceManager 進行管理,負責構建、啟停、銷毀, 銷毀的過程是異步的,先將其塞到阻塞隊列 BlockingQueue<SingleDataSource> toBeClosedDataSource
中,有一個監控線程每隔100ms從隊列中取出待關閉的ds 關閉之 (這個或許有助于配置變更時加快 GroupDataSource 的重建)
SingleDataSource的構建和初始化
SingleDataSourceManager#createDataSource()
-> initDataSourceWithFilters()
-> initDataSourceOrigin()
(1) 構建SingleDataSource對象: SingleDataSourceManager#createDataSource()
// internal use only
public SingleDataSource(DataSourceConfig config, List<JdbcFilter> filters) {
this.datasourceId = config.getId();
this.config = config;
this.punisher = new CountPunisher(this, config.getTimeWindow(), config.getPunishLimit());
this.filters = filters;
this.poolType = config.getType();
// 懶加載
this.lazyInit = config.isLazyInit();
this.withDefalutValue = true;
this.forceClose = false;
// 根據配置構建對應的底層數據庫連接池
this.dataSourcePool = DataSourcePoolFactory.buildDataSourcePool(config);
initDataSourceWithFilters(config);
}
this.poolType: 連接池類型,如 hikaricp、druid
this.lazyInit: 是否惰性初始化,默認是true, 底層連接池真正初始化的時候 會直接初始化 initialSize個物理連接,過程較慢, 如果為false 那么會影響應用啟動時間
this.dataSourcePool: 對底層連接池的包裝類, 根據 poolType 初始化對應的類型
DataSourcePool 的定義
DataSourcePool 實現類則對應各種連接池,命名規則為 xxDataSourcePool
以目前最快的連接池 hikariCP為例,適配類為 HikariDataSourcePool, #build() 返回 HikariDataSource 對象
(2) 初始化 initDataSourceWithFilters() -> initDataSourceOrigin()
initDataSourceWithFilters()
看名字,依舊是先執行以下自定義的 jdbcFilter 當前生命周期的過濾器方法 jdbcFilter#initDataSourceOrigin()
(3) initDataSourceOrigin() 初始化底層連接池
- DataSource result = this.dataSourcePool.build(value, withDefalutValue); 構建底層連接池對象, 如hikariCp的 HikariCPDataSource、 druid的DruidDataSource
- 初始化連接 如果非惰性初始化 this.lazyInit = false(默認是true) 的話才調用 getConnection() 讓底層連接池進行初始化, 否則的話不執行;
底層連接池一般是在第一次獲取連接的時候,進行初始化操作 如一次性初始化 initialSize 個物理連接,這個過程比較慢,不建議設為false
SindleDataSource#close()
當SingleDataSource#close 的時候,會一起關閉內部的 DataSourcePool 進而把底層的 連接池給關閉了