我們來談談資料庫連線池 Druid

Mondo 科技 更新 2024-01-28

在Spring Boot專案中,資料庫連線池已經成為標準配置,但是,我遇到過很多連線池異常導致業務錯誤的事故。 許多有經驗的工程師也可能不小心在這方面遇到問題。

在本文中,我們將仔細研究資料庫連線池,並解釋其實現機制,以便更好地理解和規避潛在風險。

如果沒有連線池,我們可以按如下方式操作資料庫:

應用程式使用資料庫驅動程式建立與資料庫的 TCP 連線;

使用者身份驗證;

身份驗證通過,應用讀取和寫入資料庫;

操作完成後,關閉 TCP 連線。

建立資料庫連線是一項昂貴的操作,如果同時有數百甚至數千人,頻繁的連線操作會占用更多的系統資源,但資料庫支援的連線數量有限,建立大量連線可能會導致資料庫宕機。

當我們有乙個連線池時,應用程式會提前從多個資料庫連線物件開始,然後將連線物件儲存到連線池中。 當客戶請求到達時,將從池中獲取乙個連線物件來為客戶提供服務。 請求完成後,客戶端呼叫 close 方法將連線物件放回池中。

相比之下,連線池的優點是顯而易見的:

1、資源復用:

由於資料庫連線可以復用,避免了頻繁建立,釋放了大量連線帶來的效能開銷,也增加了系統執行環境的穩定性。

2. 提高效能

當業務請求初始化時已建立的資料庫連線時,無需等待連線建立即可立即使用,從而縮短響應時間。

3. 優化資源分配

對於與多個應用共享同一資料庫的系統,可以通過在應用層配置資料庫連線池來限制乙個應用的最大可用資料庫連線數,從而防止乙個應用獨佔所有資料庫資源。

4. 連線管理

在資料庫連線池的實現中,可以按照預占用超時設定強制占用連線,避免在常規資料庫連線操作中可能出現的資源洩漏。

以下 ** 顯示了 JDBC 操作資料庫的過程:

//1.連線連線 = drivermanagergetconnection(jdbcurl, username, password);//2.執行 SQL 查詢字串 sqlquery ="select * from mytable where column1 = ?";preparedstatement preparedstatement = connection.preparestatement(sqlquery);preparedstatement.setstring(1, "somevalue");resultset = preparedstatement.executequery();//3.處理查詢結果,同時 (resultset.next())//4.關閉資源結果集close();preparedstatement.close();connection.close();
上述方法經常建立資料庫連線,偶爾在較舊的 JSP 頁面中使用,現在通常用於 JDBC 連線池。

JDBC 連線池具有標準的資料來源介面j**ax.sql.datasource,它位於 J**A 標準庫中。

public interface datasource extends commondatasource, wrapper
常用的JDBC連線池有:

hikaricp

c3p0druid

Druid(阿里巴巴資料庫連線池)是乙個開源的資料庫連線池庫,提供了強大的資料庫連線池管理和監控功能。

1. 配置 druid 資料來源

druiddatasource datasource = new druiddatasource();datasource.seturl("jdbc:mysql://localhost:3306/mydatabase");datasource.setusername("yourusername");datasource.setpassword("yourpassword");datasource.setinitialsize(5);初始連線池大小資料來源setminidle(5);最小空閒連線數資料來源setmaxactive(20);資料來源的最大活動連線數setvalidationquery("select 1 from dual");Heartbeat 的 queryDataSourcesetmaxwait(60000);最長等待時間是 datasourcesettestonborrow(true);驗證連線是否有效
2. 使用資料庫連線

connection connection = datasource.getconnection();使用連線執行資料庫操作以執行業務操作 使用連線後關閉連線Connectionclose();
3. 關閉資料來源

datasource.close();
我們學習習對資料來源的實現,可以從以下五個核心角度進行分析:

初始化。 建立連線。

*連線。 返回連線。

斷開連線。 首先,我們來看一下資料來源的實現建立聯絡介面截圖,初始化即可主動被動兩種方式。

主從是指對顯示的 init 方法的呼叫。

getconnection方法,則返回的物件是連線介面的封裝類druidconnectionholder

在初始化方法中,資料來源建立乙個包含三個連線池的陣列。

connections:用於儲存可獲取的連線物件。

evictconnections:用於儲存需要丟棄的連線物件。

keepaliveconnections:用於儲存需要保持活動狀態的連線物件。

在初始化階段,您需要將連線池化預熱也就是說,需要根據配置建立一定數量的連線,並放入池中,這樣應用在需要獲取連線時,就可以直接從池中獲取。

資料來源預熱分為:同步非同步兩種方式,見下圖:

從上圖可以看出,在同步建立連線時,原生 JDBC 會建立連線並將其直接放入 connections 陣列物件中。

非同步建立執行緒需要初始化 createscheduler,但預設未配置。

預熱資料來源後,將啟動兩個任務執行緒:建立連線。 斷開連線。

在本節中,我們將重點介紹習德魯伊資料來源建立連線。

createconnectionthread本質是一條線在無限迴圈中通過condition等待,被其他執行緒喚醒,並實現建立資料庫連線的邏輯。

筆者對執行方法進行了適當的簡化,只有滿足條件才會進行資料庫連線:

您必須儲存 ** 程式並等待,然後再建立連線。

防止建立超過最大連線數 maxacitve

建立連線物件physicalconnectioninfo之後,您需要儲存到connections陣列,並喚醒到其他執行緒,以便可以從池中獲取連線。

現在,我們已經分解了建立連線的過程,下一步是應用如何獲取它。

druiddatasource#getconnection方法將被呼叫druiddatasource#getconnectiondirect方法,實現如下。

核心流程是:

1. 在 for 迴圈中,先呼叫getconnectiondirect內在,稱為getconnectioninternal從池中獲取連線物件;

2.獲得連線後,您需要使用以下命令testonborrowtestwhileidle引數配置決定是否需要檢查連線的有效性

3.最後,如果需要判斷連線是否洩漏,請進行配置removeabandoned若要關閉長時間不適用的連線,不建議將此功能用於複製環境,僅用於連線洩漏檢測診斷。

讓我們來談談建立聯絡的重點:getconnectioninternal如何從池中獲取連線。

getconnectioninternal()有三種方法可以獲取連線:

直接建立連線(預設配置不會執行)。

您需要配置定時執行緒池createscheduler,當連線池中沒有更多可用連線時,當前借用的連線數未達到允許的最大連線數,並且當前沒有其他執行緒正在建立連線

Polllast 方法:從池中獲取連線並最多等待maxwait需要設定時間maxwait

polllast 方法的核心是在迴圈內部等待,通過條件物件 notempty 的 awaitnanos 方法,如果池中有連線,則取出最後乙個連線,並將最後乙個陣列元素留空。

TakeLast 方法:從池中獲取連線並等待,直到獲得連線。

與 polllast 方法不同,方法主體首先是內部的沒有無休止的迴圈,等待條件物件的 notempty await 方法,直到池中存在連線,取出最後乙個連線,並將最後乙個陣列元素留空。

druiddatasource在連線池中,每個物理連線都打包為:druidconnectionholder,在將其提供給應用程式執行緒之前,druidconnectionholder打包成druidpooledconnection

在每次業務操作之後,將執行本機 JDBC 操作以關閉連線,用於在連線池的情況下,就是返回連線,即將連線放回連線池中

下圖說明了這一點druidpooledconnectionclose方法:

在閉合方法中,我們專注於:recycle*連線。 方法:

我們可以簡單地理解這一點:將連線放在 connections 陣列的 poolingcount 位置,自行遞增,然後通過條件物件 notempty 喚醒等待獲取連線的應用程式。

druiddatasource連線破壞destroyconnectionthread執行緒完成:

定時任務的每個間隔(無限迴圈)。timebetweenevictionrunsmillis做一次,我們將專注於destroytaskrun方法:

destroytaskrun方法被呼叫druiddatasource#shrink方法,根據設定的條件確定哪些連線需要銷毀並保持活動狀態。

核心工藝:1. 遍歷連線池陣列

在內部,這些連線需要被銷毀或保持活動狀態,並新增到相應的容器陣列中。

2. 銷毀場景

閒暇idlemillis>= 允許的最短空閒時間minevictableidletimemillis

閒暇idlemillis>= 允許的最大空閒時間maxevictableidletimemillis

3.保持現場活躍

發生致命錯誤 (onfatalerror == true),並且致命錯誤發生在 (lastfatalerrortimemillis建立連線後。

如果開啟了keepalive機制,並且連線的空閒時間大於或等於keepalive間隔。

4.破壞連線

迴圈訪問逐出連線陣列並逐個銷毀它們。

5. 保持連線處於活動狀態

遍歷陣列 keepaliveconnections 驗證連線,如果驗證失敗,則關閉連線,否則新增鎖並重新加入連線池。

在本節中,我們將解釋如何配置合理的引數以確保資料庫連線有效。

很多同學會遇到乙個問題:“長時間不進行資料庫讀寫操作後,第一次請求資料庫時資料庫會報錯,第二次就正常了。 "

那是因為為了節省資源,資料庫會關閉長時間未讀寫的連線

筆者第一次使用德魯伊時就遇到了這樣的問題,感興趣的同學可以看看筆者的文章:

j**ayong.cn/codelife/runningforcode.html

下圖顯示了 druid 資料來源配置示例

下面我們來簡單梳理一下德魯伊的策略,確保連線有效

1. 銷毀連線線程以定時檢測所有連線,關閉空閒時間過多的連線,如果配置了 keepalive 引數,則繼續保持連線保持活動狀態

2. 每次應用程式從資料來源獲取連線時,它都會使用以下條件testonborrowtestwhileidle該引數檢測連線的有效性。

因此,我們需要重點配置以下引數:

a. Timebetweenevictionrunsmillis 引數:檢查空閒連線是否有效的頻率。

b. testwhileIdle 引數:啟用空閒連線檢測,強烈建議將其設定為 true。

C. mineVictableIdleTimeMillis 引數:連線池中連線的最大空閒時間(毫秒)、minidle >連線數>空閒時間> minevictableidletimemillis。

d. MaxevicTableidleTimeMillis 引數:連線池中連線的最大空閒時間,空閒>時間為 maxevictableidletimemillis,無論連線池中的連線數是否小於最小連線數。

E. testOnBorrow 引數如果設定為true,可以最大程度保證連線的可靠性,但效能會變得很差。

如果資料庫配置連線生存時間很短,那麼就需要適當減少空閒連線檢測間隔,減少最大和最小空閒時間。

在本文中,筆者梳理了資料庫連線池的知識點。

1. 連線池的優勢:資源復用、效能提公升、資源配置優化、連線管理;

2. JDBC連線池:實現資料來源介面j**ax.sql.datasource,位於 J**a 標準庫中;

三、連線池德魯伊的實現原則

核心方法:初始化、建立、獲取、返回和銷毀連線。

儲存容器:連線池陣列、銷毀連線陣列和保持連線陣列。

執行緒模型:獨立建立和銷毀連線線程。

鎖定機制:在建立連線和獲取連線時,會通過兩個條件物件將其鎖定emptynotempty分別控制建立連線線程和獲取連線線程的等待和喚醒。

資料庫連線池和執行緒池都是物件池的概念。 物件池是一種設計模式,用於管理可重用物件,以減少建立和銷毀物件的開銷。

筆者將在以下文章中為大家詳細講解:

如何使用池化框架commons pool

Netty 如何實現簡單的連線池。

作者:勇哥的程式設計遊記。

*:cnblogs.com/makemylife/p/17889584.html

相關問題答案

    螞蟻資料庫是國產資料庫發展的資訊創新政策支撐

    由於中國在資訊科技領域起步較晚,國內大量市場份額被國際IT巨頭佔據,甚至長期處於壟斷地位,這也給了一些國家試圖通過挑起科技和摩擦來平衡中國發展的機會。為了解決可能存在的安全風險,重要資訊系統和關鍵基礎設施使用的核心資訊科技產品和關鍵服務必須是可控的 可研究的 可開發的 可生產的。資料庫作為資訊科技發...

    資料安全知識:資料庫簡史

    第乙個自動化資料庫與赫爾曼 霍勒里斯 Herman Hollerith 相連,他於年為自動資料處理系統申請了專利。 年美國人口普查使用了打孔卡計數器系統,卡片收集代表了第乙個自動資料庫系統。每張卡片有 列,其中包含有關人員特徵的資訊。通常,人口普查資訊需要兩年時間來處理。然而,打孔卡系統和自動讀卡機...

    國產分布式資料庫AntDB資料庫發展趨勢及難點

    介紹 近日,為更好地滿足亞信科技客戶對資料管理的需求,提公升通用資料庫的產品服務能力和業務拓展能力,亞信科技分布式資料庫antdb發布了V版本幫助運營商核心系統實現業務系統的全方位自主可控和平滑上線。面向未來,國產資料庫的發展還有很長的路要走,分布式資料庫也將在這一過程中發揮重要作用。資訊創新產業,...

    資料安全知識 資料庫安全威脅

    以下是建立資料庫安全策略時必須考慮的最常見和最危險的威脅型別。SQL 注入是一種網路攻擊,攻擊者通過輸入欄位將惡意 插入結構化查詢語言 SQL 語句中。如果資料庫中存在漏洞,黑客可以繞過身份驗證並獲得向資料庫發出命令的能力。SQL 注入使入侵者能夠執行以下一項 或多項 活動 修改 竊取或刪除資料。建...

    向量資料庫,展望AGI時代

    在通向通用人工智慧 AGI 時代的道路上,向量資料庫和大型模型現在是技術領域的明星。然而,與任何新興技術一樣,它們的關注似乎更多地來自焦慮,而不是對真正需求的追求。本文探討了AGI時代對向量資料庫的熱潮及其前景,以及公眾對這一技術浪潮的心態。隨著科學技術的飛速發展,人們對AGI時代的到來充滿期待,但...