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 #標記是否刪除泄露的連接,如果空閑時間超過removeAbandonedTimeout則刪除 removeAbandoned: true #關(guān)閉abanded連接時輸出錯誤日志 logAbandoned: false #超時時間;單位為秒??臻e時間(當(dāng)前時間-連接時間)超過這個時間被刪除 removeAbandonedTimeout: 1200 #檢測取出連接池的連接是否可用,會影響性能 testOnBorrow: false #指明是否在歸還到池中前進行檢驗 testOnReturn: false #建議配置為true,不影響性能,并且保證安全性。如果testOnBorrow=true則此配置無效。申請連接的時候檢測,如果空閑時間大于timeBetweenEvictionRunsMillis,執(zhí)行validationQuery檢測連接是否有效。 testWhileIdle: true #在空閑連接回收器線程運行期間休眠的時間值,以毫秒為單位.如果設(shè)置為非正數(shù),則不運行空閑連接回收器線程。配合testWhileIdle使用 timeBetweenEvictionRunsMillis: 2000 # 下面為連接池的補充設(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ù)正常也不進行重連,客戶端對pool的請求都拒絕掉.false表示新的請求都會嘗試去數(shù)據(jù)庫請求connection.默認為false BreakAfterAcquireFailure: false #設(shè)置獲取連接出錯時的自動重連次數(shù),配合BreakAfterAcquireFailure ConnectionErrorRetryAttempts: 3 #異步初始化策略 asyncInit: true
三、連接池運行原理
1)數(shù)據(jù)庫連接池在初始化的時候會創(chuàng)建initialSize個連接,當(dāng)有數(shù)據(jù)庫操作時,會從池中取出一個連接;如果當(dāng)前池中正在使用的連接數(shù)等于maxActive,則會等待一段時間,等待其他操作釋放掉某一個連接,如果這個等待時間超過了maxWait,則會報錯;
如果當(dāng)前正在使用的連接數(shù)沒有達到maxActive,則判斷當(dāng)前是否空閑連接,如果有則直接使用空閑連接,如果沒有則新建立一個連接。
在連接使用完畢后,不是將其物理連接關(guān)閉,而是將其放入池中等待其他操作復(fù)用。
2)同時連接池內(nèi)部有機制判斷,如果當(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é)了以下幾點可供參考:
- CPU
- 磁盤IO
- 網(wǎng)絡(luò)IO
假如我們不考慮磁盤和網(wǎng)絡(luò)的影響,如果一個8核的服務(wù)器,那連接數(shù)設(shè)置為8肯定是最優(yōu)性能了,因為不需要切換上下文,如果再增加的話,肯定會因為切換上下文而影響性能。
但是數(shù)據(jù)庫在保存數(shù)據(jù)時,肯定會存儲在磁盤上,進而肯定有磁盤IO等待的時間,此時線程處于IO阻塞狀態(tài),沒啥事干,這時候操作系統(tǒng)可以將空閑的CPU核心用于其他線程。
所以當(dāng)你的線程處理是IO密集型時,可以讓連接數(shù)大一些,這樣可以在同樣的時間內(nèi),完成更多的工作。
網(wǎng)絡(luò)IO跟磁盤IO類似,在以太網(wǎng)讀寫數(shù)據(jù)時也會造成阻塞。
基于PostgreSQL基準性能測試,給出了一個連接數(shù)的計算公式:
連接數(shù) = ((核心數(shù) * 2) + 有效磁盤數(shù))
核心數(shù)不應(yīng)包含超線程(hyper thread),即使打開了超線程也是如此。
所以,連接池中的連接數(shù)量大小應(yīng)該設(shè)置成:數(shù)據(jù)庫能夠有效同時進行的查詢?nèi)蝿?wù)數(shù)(通常情況下來說不會高于 2*CPU核心數(shù))。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Springboot+WebSocket實現(xiàn)一對一聊天和公告的示例代碼
這篇文章主要介紹了Springboot+WebSocket實現(xiàn)一對一聊天和公告的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
IDEA提示內(nèi)存不足 low memory的完美解決方法(親測好用)
這篇文章主要介紹了IDEA提示內(nèi)存不足 low memory的完美解決方法(親測好用),這里以IDEA2022版本為例,在IDE中 幫助(help)–>change memory setting(改變內(nèi)存設(shè)置),具體設(shè)置辦法文中給大家詳細講解,需要的朋友可以參考下2023-01-01
Java使用LinkedHashMap進行分數(shù)排序
這篇文章主要介紹了Java使用LinkedHashMap進行分數(shù)排序的相關(guān)代碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05
SpringBoot如何監(jiān)控Redis中某個Key的變化(自定義監(jiān)聽器)
這篇文章主要介紹了SpringBoot如何監(jiān)控Redis中某個Key的變化(自定義監(jiān)聽器),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09

