Druid連接池配置過程及連接池調(diào)優(yōu)方式
一、前言
基本上來說,大部分項目都需要與數(shù)據(jù)庫交互,而要與數(shù)據(jù)庫交互的話,就不得不提數(shù)據(jù)庫連接池。
市面上的連接池也有很多,今天我們主要講一講阿里的數(shù)據(jù)庫連接池druid。
二、配置詳解
初始化連接
initialSize: 50 # 最大活動連接數(shù) maxActive: 100 maxPoolPreparedStatementPerConnectionSize: 50 # 最大超時等待時間,單位毫秒 maxWait: 60000 # 配置一個連接在池中最小生存的時間(當(dāng)前時間-最后活動時間),單位是毫秒 minEvictableIdleTimeMillis: 300000 maxEvictableIdleTimeMillis: 900000 # 最小空閑連接:連接池中容許保持空閑狀態(tài)的最小連接數(shù)量,低于這個數(shù)量將創(chuàng)建新的連接, minIdle: 10 # 打開PSCache,并且指定每個連接上PSCache的大小 poolPreparedStatements: true #標(biāo)記是否刪除泄露的連接,如果空閑時間超過removeAbandonedTimeout則刪除 removeAbandoned: true #關(guān)閉abanded連接時輸出錯誤日志 logAbandoned: false #超時時間;單位為秒??臻e時間(當(dāng)前時間-連接時間)超過這個時間被刪除 removeAbandonedTimeout: 1200 #檢測取出連接池的連接是否可用,會影響性能 testOnBorrow: false #指明是否在歸還到池中前進(jìn)行檢驗 testOnReturn: false #建議配置為true,不影響性能,并且保證安全性。如果testOnBorrow=true則此配置無效。申請連接的時候檢測,如果空閑時間大于timeBetweenEvictionRunsMillis,執(zhí)行validationQuery檢測連接是否有效。 testWhileIdle: true #在空閑連接回收器線程運(yùn)行期間休眠的時間值,以毫秒為單位.如果設(shè)置為非正數(shù),則不運(yùn)行空閑連接回收器線程。配合testWhileIdle使用 timeBetweenEvictionRunsMillis: 2000 # 下面為連接池的補(bǔ)充設(shè)置,應(yīng)用到上面所有數(shù)據(jù)源中 type: com.alibaba.druid.pool.DruidDataSource #校驗的sql validationQuery: SELECT 1 FROM DUAL #設(shè)置獲取連接時的重試次數(shù),-1為不重試 NotFullTimeoutRetryCount: 3 #true表示向數(shù)據(jù)庫請求連接失敗后,就算后端數(shù)據(jù)庫恢復(fù)正常也不進(jìn)行重連,客戶端對pool的請求都拒絕掉.false表示新的請求都會嘗試去數(shù)據(jù)庫請求connection.默認(rèn)為false BreakAfterAcquireFailure: false #設(shè)置獲取連接出錯時的自動重連次數(shù),配合BreakAfterAcquireFailure ConnectionErrorRetryAttempts: 3 #異步初始化策略 asyncInit: true
三、連接池運(yùn)行原理
1)數(shù)據(jù)庫連接池在初始化的時候會創(chuàng)建initialSize個連接,當(dāng)有數(shù)據(jù)庫操作時,會從池中取出一個連接;如果當(dāng)前池中正在使用的連接數(shù)等于maxActive,則會等待一段時間,等待其他操作釋放掉某一個連接,如果這個等待時間超過了maxWait,則會報錯;
如果當(dāng)前正在使用的連接數(shù)沒有達(dá)到maxActive,則判斷當(dāng)前是否空閑連接,如果有則直接使用空閑連接,如果沒有則新建立一個連接。
在連接使用完畢后,不是將其物理連接關(guān)閉,而是將其放入池中等待其他操作復(fù)用。
2)同時連接池內(nèi)部有機(jī)制判斷,如果當(dāng)前的總的連接數(shù)少于miniIdle,則會建立新的空閑連接,以保證連接數(shù)得到miniIdle。
如果當(dāng)前連接池中某個連接在空閑了timeBetweenEvictionRunsMillis時間后仍然沒有使用,則被物理性的關(guān)閉掉。
有些數(shù)據(jù)庫連接的時候有超時限制(mysql連接在8小時后斷開),或者由于網(wǎng)絡(luò)中斷等原因,連接池的連接會出現(xiàn)失效的情況,這時候設(shè)置一個testWhileIdle參數(shù)為true,可以保證連接池內(nèi)部定時檢測連接的可用性,不可用的連接會被拋棄或者重建,最大情況的保證從連接池中得到的Connection對象是可用的。
當(dāng)然,為了保證絕對的可用性,你也可以使用testOnBorrow為true(即在獲取Connection對象時檢測其可用性),不過這樣會影響性能。
四、關(guān)于調(diào)優(yōu)
關(guān)于調(diào)優(yōu),主要是該如何設(shè)置連接池大小呢?
可以很直接的說,關(guān)于數(shù)據(jù)庫連接池大小的設(shè)置,大部分程序員可能都會依靠自己的直覺去設(shè)置它的大小。
其實連接數(shù)設(shè)置多大合適,取決于很多因素,我總結(jié)了以下幾點(diǎn)可供參考:
- CPU
- 磁盤IO
- 網(wǎng)絡(luò)IO
假如我們不考慮磁盤和網(wǎng)絡(luò)的影響,如果一個8核的服務(wù)器,那連接數(shù)設(shè)置為8肯定是最優(yōu)性能了,因為不需要切換上下文,如果再增加的話,肯定會因為切換上下文而影響性能。
但是數(shù)據(jù)庫在保存數(shù)據(jù)時,肯定會存儲在磁盤上,進(jìn)而肯定有磁盤IO等待的時間,此時線程處于IO阻塞狀態(tài),沒啥事干,這時候操作系統(tǒng)可以將空閑的CPU核心用于其他線程。
所以當(dāng)你的線程處理是IO密集型時,可以讓連接數(shù)大一些,這樣可以在同樣的時間內(nèi),完成更多的工作。
網(wǎng)絡(luò)IO跟磁盤IO類似,在以太網(wǎng)讀寫數(shù)據(jù)時也會造成阻塞。
基于PostgreSQL基準(zhǔn)性能測試,給出了一個連接數(shù)的計算公式:
連接數(shù) = ((核心數(shù) * 2) + 有效磁盤數(shù))
核心數(shù)不應(yīng)包含超線程(hyper thread),即使打開了超線程也是如此。
所以,連接池中的連接數(shù)量大小應(yīng)該設(shè)置成:數(shù)據(jù)庫能夠有效同時進(jìn)行的查詢?nèi)蝿?wù)數(shù)(通常情況下來說不會高于 2*CPU核心數(shù))。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
IDEA導(dǎo)入JDBC驅(qū)動的jar包步驟詳解
JDBC是一種底層的API,是連接數(shù)據(jù)庫和Java應(yīng)用程序的紐帶,因此我們在訪問數(shù)據(jù)庫時需要在業(yè)務(wù)邏輯層中嵌入SQL語句,這篇文章主要介紹了IDEA導(dǎo)入JDBC驅(qū)動的jar包,需要的朋友可以參考下2023-07-07
怎樣通過分析GC日志來定位Java進(jìn)程的內(nèi)存問題
這篇文章主要介紹了怎樣通過分析GC日志來定位Java進(jìn)程的內(nèi)存問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-07-07
Java中HTTP GET方法調(diào)用帶有body的問題解決
這篇文章主要為大家詳細(xì)介紹了Java如何解決HTTP GET方法調(diào)用帶有body的問題,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以參考一下2024-02-02
Java的作業(yè)調(diào)度類庫Quartz基本使用指南
這篇文章主要介紹了Java的作業(yè)調(diào)度類庫Quartz基本使用指南,Quartz能夠讓類按照指定的計劃順序執(zhí)行,需要的朋友可以參考下2016-03-03
Java多線程 生產(chǎn)者消費(fèi)者模型實例詳解
這篇文章主要介紹了Java多線程 生產(chǎn)者消費(fèi)者模型實例詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-09-09
SpringBoot項目在啟動后自動關(guān)閉的實現(xiàn)
我們在寫spring?boot?web項目時,有時會遇到啟動后立即關(guān)閉的情況,?本文主要介紹了SpringBoot項目在啟動后自動關(guān)閉的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2024-01-01
JVM默認(rèn)時區(qū)為:Asia/Shanghai與java程序中GMT+08不一致異常
這篇文章主要介紹了JVM默認(rèn)時區(qū)為:Asia/Shanghai與java程序中GMT+08不一致異常問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10

