Druid連接池配置過(guò)程及連接池調(diào)優(yōu)方式
一、前言
基本上來(lái)說(shuō),大部分項(xiàng)目都需要與數(shù)據(jù)庫(kù)交互,而要與數(shù)據(jù)庫(kù)交互的話,就不得不提數(shù)據(jù)庫(kù)連接池。
市面上的連接池也有很多,今天我們主要講一講阿里的數(shù)據(jù)庫(kù)連接池druid。
二、配置詳解
初始化連接
initialSize: 50 # 最大活動(dòng)連接數(shù) maxActive: 100 maxPoolPreparedStatementPerConnectionSize: 50 # 最大超時(shí)等待時(shí)間,單位毫秒 maxWait: 60000 # 配置一個(gè)連接在池中最小生存的時(shí)間(當(dāng)前時(shí)間-最后活動(dòng)時(shí)間),單位是毫秒 minEvictableIdleTimeMillis: 300000 maxEvictableIdleTimeMillis: 900000 # 最小空閑連接:連接池中容許保持空閑狀態(tài)的最小連接數(shù)量,低于這個(gè)數(shù)量將創(chuàng)建新的連接, minIdle: 10 # 打開(kāi)PSCache,并且指定每個(gè)連接上PSCache的大小 poolPreparedStatements: true #標(biāo)記是否刪除泄露的連接,如果空閑時(shí)間超過(guò)removeAbandonedTimeout則刪除 removeAbandoned: true #關(guān)閉abanded連接時(shí)輸出錯(cuò)誤日志 logAbandoned: false #超時(shí)時(shí)間;單位為秒??臻e時(shí)間(當(dāng)前時(shí)間-連接時(shí)間)超過(guò)這個(gè)時(shí)間被刪除 removeAbandonedTimeout: 1200 #檢測(cè)取出連接池的連接是否可用,會(huì)影響性能 testOnBorrow: false #指明是否在歸還到池中前進(jìn)行檢驗(yàn) testOnReturn: false #建議配置為true,不影響性能,并且保證安全性。如果testOnBorrow=true則此配置無(wú)效。申請(qǐng)連接的時(shí)候檢測(cè),如果空閑時(shí)間大于timeBetweenEvictionRunsMillis,執(zhí)行validationQuery檢測(cè)連接是否有效。 testWhileIdle: true #在空閑連接回收器線程運(yùn)行期間休眠的時(shí)間值,以毫秒為單位.如果設(shè)置為非正數(shù),則不運(yùn)行空閑連接回收器線程。配合testWhileIdle使用 timeBetweenEvictionRunsMillis: 2000 # 下面為連接池的補(bǔ)充設(shè)置,應(yīng)用到上面所有數(shù)據(jù)源中 type: com.alibaba.druid.pool.DruidDataSource #校驗(yàn)的sql validationQuery: SELECT 1 FROM DUAL #設(shè)置獲取連接時(shí)的重試次數(shù),-1為不重試 NotFullTimeoutRetryCount: 3 #true表示向數(shù)據(jù)庫(kù)請(qǐng)求連接失敗后,就算后端數(shù)據(jù)庫(kù)恢復(fù)正常也不進(jìn)行重連,客戶端對(duì)pool的請(qǐng)求都拒絕掉.false表示新的請(qǐng)求都會(huì)嘗試去數(shù)據(jù)庫(kù)請(qǐng)求connection.默認(rèn)為false BreakAfterAcquireFailure: false #設(shè)置獲取連接出錯(cuò)時(shí)的自動(dòng)重連次數(shù),配合BreakAfterAcquireFailure ConnectionErrorRetryAttempts: 3 #異步初始化策略 asyncInit: true
三、連接池運(yùn)行原理
1)數(shù)據(jù)庫(kù)連接池在初始化的時(shí)候會(huì)創(chuàng)建initialSize個(gè)連接,當(dāng)有數(shù)據(jù)庫(kù)操作時(shí),會(huì)從池中取出一個(gè)連接;如果當(dāng)前池中正在使用的連接數(shù)等于maxActive,則會(huì)等待一段時(shí)間,等待其他操作釋放掉某一個(gè)連接,如果這個(gè)等待時(shí)間超過(guò)了maxWait,則會(huì)報(bào)錯(cuò);
如果當(dāng)前正在使用的連接數(shù)沒(méi)有達(dá)到maxActive,則判斷當(dāng)前是否空閑連接,如果有則直接使用空閑連接,如果沒(méi)有則新建立一個(gè)連接。
在連接使用完畢后,不是將其物理連接關(guān)閉,而是將其放入池中等待其他操作復(fù)用。
2)同時(shí)連接池內(nèi)部有機(jī)制判斷,如果當(dāng)前的總的連接數(shù)少于miniIdle,則會(huì)建立新的空閑連接,以保證連接數(shù)得到miniIdle。
如果當(dāng)前連接池中某個(gè)連接在空閑了timeBetweenEvictionRunsMillis時(shí)間后仍然沒(méi)有使用,則被物理性的關(guān)閉掉。
有些數(shù)據(jù)庫(kù)連接的時(shí)候有超時(shí)限制(mysql連接在8小時(shí)后斷開(kāi)),或者由于網(wǎng)絡(luò)中斷等原因,連接池的連接會(huì)出現(xiàn)失效的情況,這時(shí)候設(shè)置一個(gè)testWhileIdle參數(shù)為true,可以保證連接池內(nèi)部定時(shí)檢測(cè)連接的可用性,不可用的連接會(huì)被拋棄或者重建,最大情況的保證從連接池中得到的Connection對(duì)象是可用的。
當(dāng)然,為了保證絕對(duì)的可用性,你也可以使用testOnBorrow為true(即在獲取Connection對(duì)象時(shí)檢測(cè)其可用性),不過(guò)這樣會(huì)影響性能。
四、關(guān)于調(diào)優(yōu)
關(guān)于調(diào)優(yōu),主要是該如何設(shè)置連接池大小呢?
可以很直接的說(shuō),關(guān)于數(shù)據(jù)庫(kù)連接池大小的設(shè)置,大部分程序員可能都會(huì)依靠自己的直覺(jué)去設(shè)置它的大小。
其實(shí)連接數(shù)設(shè)置多大合適,取決于很多因素,我總結(jié)了以下幾點(diǎn)可供參考:
- CPU
- 磁盤(pán)IO
- 網(wǎng)絡(luò)IO
假如我們不考慮磁盤(pán)和網(wǎng)絡(luò)的影響,如果一個(gè)8核的服務(wù)器,那連接數(shù)設(shè)置為8肯定是最優(yōu)性能了,因?yàn)椴恍枰袚Q上下文,如果再增加的話,肯定會(huì)因?yàn)榍袚Q上下文而影響性能。
但是數(shù)據(jù)庫(kù)在保存數(shù)據(jù)時(shí),肯定會(huì)存儲(chǔ)在磁盤(pán)上,進(jìn)而肯定有磁盤(pán)IO等待的時(shí)間,此時(shí)線程處于IO阻塞狀態(tài),沒(méi)啥事干,這時(shí)候操作系統(tǒng)可以將空閑的CPU核心用于其他線程。
所以當(dāng)你的線程處理是IO密集型時(shí),可以讓連接數(shù)大一些,這樣可以在同樣的時(shí)間內(nèi),完成更多的工作。
網(wǎng)絡(luò)IO跟磁盤(pán)IO類似,在以太網(wǎng)讀寫(xiě)數(shù)據(jù)時(shí)也會(huì)造成阻塞。
基于PostgreSQL基準(zhǔn)性能測(cè)試,給出了一個(gè)連接數(shù)的計(jì)算公式:
連接數(shù) = ((核心數(shù) * 2) + 有效磁盤(pán)數(shù))
核心數(shù)不應(yīng)包含超線程(hyper thread),即使打開(kāi)了超線程也是如此。
所以,連接池中的連接數(shù)量大小應(yīng)該設(shè)置成:數(shù)據(jù)庫(kù)能夠有效同時(shí)進(jìn)行的查詢?nèi)蝿?wù)數(shù)(通常情況下來(lái)說(shuō)不會(huì)高于 2*CPU核心數(shù))。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Springboot+WebSocket實(shí)現(xiàn)一對(duì)一聊天和公告的示例代碼
這篇文章主要介紹了Springboot+WebSocket實(shí)現(xiàn)一對(duì)一聊天和公告的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
IDEA提示內(nèi)存不足 low memory的完美解決方法(親測(cè)好用)
這篇文章主要介紹了IDEA提示內(nèi)存不足 low memory的完美解決方法(親測(cè)好用),這里以IDEA2022版本為例,在IDE中 幫助(help)–>change memory setting(改變內(nèi)存設(shè)置),具體設(shè)置辦法文中給大家詳細(xì)講解,需要的朋友可以參考下2023-01-01
Java使用LinkedHashMap進(jìn)行分?jǐn)?shù)排序
這篇文章主要介紹了Java使用LinkedHashMap進(jìn)行分?jǐn)?shù)排序的相關(guān)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05
java創(chuàng)建多級(jí)目錄文件的實(shí)例講解
下面小編就為大家分享一篇java創(chuàng)建多級(jí)目錄文件的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
SpringBoot如何監(jiān)控Redis中某個(gè)Key的變化(自定義監(jiān)聽(tīng)器)
這篇文章主要介紹了SpringBoot如何監(jiān)控Redis中某個(gè)Key的變化(自定義監(jiān)聽(tīng)器),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
java實(shí)現(xiàn)圖片文字識(shí)別ocr
這篇文章主要介紹了java實(shí)現(xiàn)圖片文字識(shí)別ocr ,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-08-08

