數(shù)據(jù)庫(kù)連接池如何配置-創(chuàng)新互聯(lián)

這篇文章將為大家詳細(xì)講解有關(guān)數(shù)據(jù)庫(kù)連接池如何配置,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

創(chuàng)新互聯(lián)建站為您提適合企業(yè)的網(wǎng)站設(shè)計(jì)?讓您的網(wǎng)站在搜索引擎具有高度排名,讓您的網(wǎng)站具備超強(qiáng)的網(wǎng)絡(luò)競(jìng)爭(zhēng)力!結(jié)合企業(yè)自身,進(jìn)行網(wǎng)站設(shè)計(jì)及把握,最后結(jié)合企業(yè)文化和具體宗旨等,才能創(chuàng)作出一份性化解決方案。從網(wǎng)站策劃到成都網(wǎng)站制作、做網(wǎng)站, 我們的網(wǎng)頁(yè)設(shè)計(jì)師為您提供的解決方案。

一、連接池配置


1.1 maxWait

參數(shù)表示從連接池獲取連接的超時(shí)等待時(shí)間,單位毫秒,需要注意這個(gè)參數(shù)只管理獲取連接的超時(shí)。獲取連接等待的直接原因是池子里沒有可用連接,具體包括:連接池未初始化,連接長(zhǎng)久未使用已被釋放,連接使用中需要新建連接,或連接池已耗盡需等待連接用完后歸還。這里有一個(gè)很關(guān)鍵的點(diǎn)是 maxWait 未配置或者配置為 0 時(shí),表示不設(shè)等待超時(shí)時(shí)間(可能與一些人認(rèn)為 -1 表示無(wú)限等待的預(yù)期不符合,雖然在 druid 中 maxWait 配置成 -1 的含義也相同)。對(duì)實(shí)現(xiàn)細(xì)節(jié)感興趣的讀者可以從 com.alibaba.druid.pool.DruidDataSource#getConnection 方法入手,查看參數(shù)的使用邏輯。

推薦配置:內(nèi)網(wǎng)(網(wǎng)絡(luò)狀況好) 800;網(wǎng)絡(luò)狀況不是特別好的情況下推薦大于等于 1200,因?yàn)?tcp 建連重試一般是 1 秒。

如果不配置maxWait,后果會(huì)怎么樣呢?可能有些應(yīng)用就這么干的,而且也沒發(fā)生過異常,不過最終墨菲定律還是會(huì)顯靈的,下面來看幾個(gè)真實(shí)的案例:

案例一

// 參數(shù)配置

maxWait=0,
maxActive=5,

正常流量下業(yè)務(wù)沒有發(fā)現(xiàn)任何問題,但突發(fā)大流量涌入時(shí),造成連接池耗盡,所有新增的DB請(qǐng)求處于等待獲取連接的狀態(tài)中。由于 maxWait=0 表示無(wú)限等待,在請(qǐng)求速度大于處理速度的情況下等待隊(duì)列會(huì)越排越長(zhǎng),最終業(yè)務(wù)上的表現(xiàn)就是業(yè)務(wù)接口大量超時(shí),流量越大造成實(shí)際吞吐量反而越低。

案例二

maxWait=0,

removeAbandoned=true,
removeAbandonedTimeout=180,

現(xiàn)象:業(yè)務(wù)代碼正常運(yùn)行了很長(zhǎng)時(shí)間沒有出現(xiàn)過消息積壓情況,在一次全鏈路壓測(cè)后產(chǎn)生大量的壓測(cè)數(shù)據(jù),造成了 MQ 消息的堆積。即使重啟服務(wù),也只能保持幾十秒的正常運(yùn)行,隨后又進(jìn)入消費(fèi)停滯的狀態(tài)。使用 jstack 發(fā)現(xiàn)是卡在獲取數(shù)據(jù)庫(kù)連接中,再過3分鐘左右后出現(xiàn)錯(cuò)誤:abandon connection, owner thread: xxx 。最后業(yè)務(wù)通過配置 maxWait=3000(3秒超時(shí)),業(yè)務(wù) MQ 消息正常消費(fèi)。

原因分析:業(yè)務(wù)依賴兩個(gè)數(shù)據(jù)源,這里表示為 datasource1 與 datasource2,其中在部分代碼段中同時(shí)開啟了兩個(gè)庫(kù)的事務(wù)。如圖1 所示,線程1 獲取了 datasource1 中的最后一個(gè)連接 connection[n],等待獲取 datasource2 的連接,此時(shí)線程2也正在執(zhí)行類似的操作,造成了死鎖等待。大家對(duì)這種互鎖一定很熟悉,只是這次是發(fā)生在 DB 上。為什么一段時(shí)間后程序報(bào) abandon connection 的錯(cuò)誤,這是因?yàn)榕渲昧?{removeAbandoned:true, removeAbandonedTimeout:180} 這兩個(gè)參數(shù),這個(gè)配置的含義是如果一個(gè)連接持有 180 秒還沒有歸還,就被認(rèn)為是異常連接(對(duì)于 OLTP 的業(yè)務(wù)查詢通常都是毫秒級(jí)的),需要關(guān)閉掉這條連接。之所以正常情況下沒有發(fā)生問題是因?yàn)檫B接池水位比較低,資源充足沒有造成相互等待的情況。

數(shù)據(jù)庫(kù)連接池如何配置

圖1. 雙DB連接池死鎖問題

1.2 connectionProperties


參數(shù)是以鍵值對(duì)表示的字符串,其中可以配置 connectTimeout 和 socketTimeout,它們的單位都是毫秒,這兩個(gè)參數(shù)在應(yīng)對(duì)網(wǎng)絡(luò)異常方面非常重要。connectTimeout 配置建立 TCP 連接的超時(shí)時(shí)間,socketTimeout 配置發(fā)送請(qǐng)求后等待響應(yīng)的超時(shí)時(shí)間。這兩個(gè)參數(shù)也可以通過在 jdbc url 中添加 connectTimeout=xxx&socketTimeout=xxx 的方式配置,試過在 connectinoProperties 中和 jdbc url 兩個(gè)地方都配置,發(fā)現(xiàn)優(yōu)先使用 connectionProperties 中的配置。如果不設(shè)置這兩項(xiàng)超時(shí)時(shí)間,服務(wù)會(huì)有非常高的風(fēng)險(xiǎn)?,F(xiàn)實(shí)案例是在網(wǎng)絡(luò)異常后發(fā)現(xiàn)應(yīng)用無(wú)法連接到 DB,但是重啟后卻能正常的訪問 DB。因?yàn)樵诰W(wǎng)絡(luò)異常下 socket 沒有辦法檢測(cè)到網(wǎng)絡(luò)錯(cuò)誤,這時(shí)連接其實(shí)已經(jīng)變?yōu)椤八肋B接”,如果沒有設(shè)置 socket 網(wǎng)絡(luò)超時(shí),連接就會(huì)一直等待 DB 返回結(jié)果,造成新的請(qǐng)求都無(wú)法獲取到連接。

推薦配置:
socketTimeout=3000;connectTimeout=1200

1.3 keepAlive


參數(shù)表示是否對(duì)空閑連接保活,布爾類型??赡懿簧偃苏J(rèn)為 druid 連接池默認(rèn)會(huì)維持DB連接的心跳,對(duì)池子中的連接進(jìn)行保活,特別配置了 minIdle 這個(gè)參數(shù)后覺得,有了 minIdle 最少應(yīng)該會(huì)保持這么多空閑連接。其實(shí),keepAlive 這個(gè)參數(shù)是在 druid 1.0.28 后新增的,并且默認(rèn)值是 false,即不進(jìn)行連接?;?。

那么需要保活連接,是不是將 keepAlive 配置成 true 就完事了呢?雖然 true 的確是開啟了?;顧C(jī)制,但是應(yīng)該?;疃嗌賯€(gè),心跳檢查的規(guī)則是什么,這些都需要正確配置,否則還是可能事與愿違。這里需要了解幾個(gè)相關(guān)的參數(shù):minIdle 最小連接池?cái)?shù)量,連接?;畹臄?shù)量,空閑連接超時(shí)踢除過程會(huì)保留的連接數(shù)(前提是當(dāng)前連接數(shù)大于等于 minIdle),其實(shí) keepAlive 也僅維護(hù)已存在的連接,而不會(huì)去新建連接,即使連接數(shù)小于 minIdle;minEvictableIdleTimeMillis 單位毫秒,連接保持空閑而不被驅(qū)逐的最小時(shí)間,?;钚奶粚?duì)存活時(shí)間超過這個(gè)值的連接進(jìn)行;maxEvictableIdleTimeMillis 單位毫秒,連接保持空閑的最長(zhǎng)時(shí)間,如果連接執(zhí)行過任何操作后計(jì)時(shí)器就會(huì)被重置(包括心跳保活動(dòng)作);timeBetweenEvictionRunsMillis 單位毫秒,Destroy 線程檢測(cè)連接的間隔時(shí)間,會(huì)在檢測(cè)過程中觸發(fā)心跳。保活檢查的詳細(xì)流程可參見源碼com.alibaba.druid.pool.DruidDataSource.DestroyTask,其中心跳檢查會(huì)根據(jù)配置使用 ping 或 validationQuery 配置的檢查語(yǔ)句。

推薦配置:如果網(wǎng)絡(luò)狀況不佳,程序啟動(dòng)慢或者經(jīng)常出現(xiàn)突發(fā)流量,則推薦配置為true;

案例一

keepAlive=true,
minIdle=5,
timeBetweenEvictionRunsMillis=10000,
minEvictableIdleTimeMillis=100000,
maxEvictableIdleTimeMillis=100000,

請(qǐng)問上述配置連接能?;畛晒??不能,由于 minEvictableIdleTimeMillis == maxEvictableIdleTimeMillis,所以連接在開始檢測(cè)時(shí)就會(huì)被斷定超過 maxEvictableIdleTimeMillis 需要丟棄。

案例二

keepAlive=true,
minIdle=5,
timeBetweenEvictionRunsMillis=10000,
minEvictableIdleTimeMillis=95000,
maxEvictableIdleTimeMillis=100000,

請(qǐng)問上述配置連接能?;畛晒??具有隨機(jī)性,由于 maxEvictableIdleTimeMillis - minEvictableIdleTimeMillis < timeBetweenEvictionRunsMillis,所以有可能在這個(gè)窗口期并沒有執(zhí)行 Destroy 線程檢測(cè)任務(wù),無(wú)法保證心跳一定會(huì)被執(zhí)行。

1.4 maxActive


大連接池?cái)?shù)量,允許的大同時(shí)使用中的連接數(shù)。這里特地嘮叨一下,配置 maxActive 千萬(wàn)不要好大喜多,雖然配置大了看起來業(yè)務(wù)流量飆升后還能處理更多的請(qǐng)求,但切換到 DB 視角會(huì)發(fā)現(xiàn)其實(shí)連接數(shù)的增多在很多場(chǎng)景下反而會(huì)減低吞吐量,一個(gè)非常典型的例子就秒殺,在更新熱點(diǎn)數(shù)據(jù)時(shí) DB 需要加鎖操作,這個(gè)時(shí)候再讓更多的連接操作 DB 就有點(diǎn)像假日往高速上涌入的車輛,只會(huì)給 DB 添堵。

推薦配置:20,多數(shù)場(chǎng)景下 20 已完全夠用,當(dāng)然這個(gè)參數(shù)跟使用場(chǎng)景相關(guān)性很大,一般配置成正常連接數(shù)的 3~5 倍。

二、DB“慢查”排查記


上面講了一些配置的坑,那么是否中規(guī)中矩的按照推薦配置就萬(wàn)事大吉了呢,現(xiàn)實(shí)中的世界往往沒這么簡(jiǎn)單的事,下面分享一個(gè)“慢查”排查的一個(gè)案例,了解一下DB慢查的排查思路。

有應(yīng)用反饋發(fā)現(xiàn)大量 DB 慢查,并且日志上還記錄了詳細(xì)的執(zhí)行時(shí)間和SQL語(yǔ)句。接到問題后我們第一時(shí)間排查 DB 發(fā)現(xiàn)并沒有異常,也沒有慢查記錄,并且日志中的大部分 SQL 都能匹配索引,測(cè)試執(zhí)行都在毫秒級(jí)。于是開始排查網(wǎng)絡(luò)是否正常,有沒丟包、重傳等現(xiàn)象,查詢監(jiān)控?cái)?shù)據(jù)發(fā)現(xiàn)也很正常,然后進(jìn)行抓包分析發(fā)現(xiàn)實(shí)際請(qǐng)求處理的速度非常正常,至此可以排除 DB 問題。

于是再深入分析,查詢 DB 其實(shí)可分為兩個(gè)階段:1. 獲取連接階段;2. 執(zhí)行查詢階段;絕大部分情況下獲取連接代價(jià)非常小,直接就能從連接池獲取到,即使需要新建連接代價(jià)往往也不大,所以使用時(shí)非常容易忽略獲取連接這個(gè)階段。什么情況下獲取連接會(huì)出問題呢?一種情況是建立連接慢,一種是連接池已經(jīng)耗盡,再對(duì)照上面的案例進(jìn)行排查,依次排除了這兩種情況。至此問題還是一籌莫展,還好高手在場(chǎng),想到用 strace 跟蹤 SQL 請(qǐng)求前后干了什么,最后發(fā)現(xiàn)記錄慢查日志開始和結(jié)束之間有寫日志操作,這里的寫日志是同步的并且在特定情況下正好觸發(fā)了另一個(gè)問題導(dǎo)致寫日志非常慢,并且這個(gè)日志操作是封裝在底層的,連業(yè)務(wù)開發(fā)都不清楚有這么個(gè)操作。至此真相水落石出,最終修復(fù)了寫日志慢的問題后就不再出現(xiàn)類似的“慢查”了。

關(guān)于“數(shù)據(jù)庫(kù)連接池如何配置”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

網(wǎng)站欄目:數(shù)據(jù)庫(kù)連接池如何配置-創(chuàng)新互聯(lián)
URL地址:http://www.bm7419.com/article0/ihcio.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機(jī)網(wǎng)站建設(shè)、電子商務(wù)、企業(yè)網(wǎng)站制作網(wǎng)站內(nèi)鏈、網(wǎng)頁(yè)設(shè)計(jì)公司、軟件開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)