亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

數據庫連接池如何配置

發布時間:2021-12-08 09:33:58 來源:億速云 閱讀:874 作者:小新 欄目:數據庫

這篇文章將為大家詳細講解有關數據庫連接池如何配置,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

一、連接池配置


1.1 maxWait

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

推薦配置:內網(網絡狀況好) 800;網絡狀況不是特別好的情況下推薦大于等于 1200,因為 tcp 建連重試一般是 1 秒。

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

案例一

// 參數配置

maxWait=0,
maxActive=5,

正常流量下業務沒有發現任何問題,但突發大流量涌入時,造成連接池耗盡,所有新增的DB請求處于等待獲取連接的狀態中。由于 maxWait=0 表示無限等待,在請求速度大于處理速度的情況下等待隊列會越排越長,最終業務上的表現就是業務接口大量超時,流量越大造成實際吞吐量反而越低。

案例二

maxWait=0,

removeAbandoned=true,
removeAbandonedTimeout=180,

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

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

數據庫連接池如何配置

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

1.2 connectionProperties


參數是以鍵值對表示的字符串,其中可以配置 connectTimeout 和 socketTimeout,它們的單位都是毫秒,這兩個參數在應對網絡異常方面非常重要。connectTimeout 配置建立 TCP 連接的超時時間,socketTimeout 配置發送請求后等待響應的超時時間。這兩個參數也可以通過在 jdbc url 中添加 connectTimeout=xxx&socketTimeout=xxx 的方式配置,試過在 connectinoProperties 中和 jdbc url 兩個地方都配置,發現優先使用 connectionProperties 中的配置。如果不設置這兩項超時時間,服務會有非常高的風險。現實案例是在網絡異常后發現應用無法連接到 DB,但是重啟后卻能正常的訪問 DB。因為在網絡異常下 socket 沒有辦法檢測到網絡錯誤,這時連接其實已經變為“死連接”,如果沒有設置 socket 網絡超時,連接就會一直等待 DB 返回結果,造成新的請求都無法獲取到連接。

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

1.3 keepAlive


參數表示是否對空閑連接保活,布爾類型。可能不少人認為 druid 連接池默認會維持DB連接的心跳,對池子中的連接進行保活,特別配置了 minIdle 這個參數后覺得,有了 minIdle 最少應該會保持這么多空閑連接。其實,keepAlive 這個參數是在 druid 1.0.28 后新增的,并且默認值是 false,即不進行連接保活。

那么需要保活連接,是不是將 keepAlive 配置成 true 就完事了呢?雖然 true 的確是開啟了保活機制,但是應該保活多少個,心跳檢查的規則是什么,這些都需要正確配置,否則還是可能事與愿違。這里需要了解幾個相關的參數:minIdle 最小連接池數量,連接保活的數量,空閑連接超時踢除過程會保留的連接數(前提是當前連接數大于等于 minIdle),其實 keepAlive 也僅維護已存在的連接,而不會去新建連接,即使連接數小于 minIdle;minEvictableIdleTimeMillis 單位毫秒,連接保持空閑而不被驅逐的最小時間,保活心跳只對存活時間超過這個值的連接進行;maxEvictableIdleTimeMillis 單位毫秒,連接保持空閑的最長時間,如果連接執行過任何操作后計時器就會被重置(包括心跳保活動作);timeBetweenEvictionRunsMillis 單位毫秒,Destroy 線程檢測連接的間隔時間,會在檢測過程中觸發心跳。保活檢查的詳細流程可參見源碼com.alibaba.druid.pool.DruidDataSource.DestroyTask,其中心跳檢查會根據配置使用 ping 或 validationQuery 配置的檢查語句。

推薦配置:如果網絡狀況不佳,程序啟動慢或者經常出現突發流量,則推薦配置為true;

案例一

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

請問上述配置連接能保活成功嗎?不能,由于 minEvictableIdleTimeMillis == maxEvictableIdleTimeMillis,所以連接在開始檢測時就會被斷定超過 maxEvictableIdleTimeMillis 需要丟棄。

案例二

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

請問上述配置連接能保活成功嗎?具有隨機性,由于 maxEvictableIdleTimeMillis - minEvictableIdleTimeMillis < timeBetweenEvictionRunsMillis,所以有可能在這個窗口期并沒有執行 Destroy 線程檢測任務,無法保證心跳一定會被執行。

1.4 maxActive


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

推薦配置:20,多數場景下 20 已完全夠用,當然這個參數跟使用場景相關性很大,一般配置成正常連接數的 3~5 倍。

二、DB“慢查”排查記


上面講了一些配置的坑,那么是否中規中矩的按照推薦配置就萬事大吉了呢,現實中的世界往往沒這么簡單的事,下面分享一個“慢查”排查的一個案例,了解一下DB慢查的排查思路。

有應用反饋發現大量 DB 慢查,并且日志上還記錄了詳細的執行時間和SQL語句。接到問題后我們第一時間排查 DB 發現并沒有異常,也沒有慢查記錄,并且日志中的大部分 SQL 都能匹配索引,測試執行都在毫秒級。于是開始排查網絡是否正常,有沒丟包、重傳等現象,查詢監控數據發現也很正常,然后進行抓包分析發現實際請求處理的速度非常正常,至此可以排除 DB 問題。

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

關于“數據庫連接池如何配置”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

双柏县| 黎城县| 宜宾县| 安塞县| 白沙| 城固县| 永昌县| 广西| 威远县| 海伦市| 珲春市| 咸宁市| 二连浩特市| 饶河县| 和田县| 乐平市| 合作市| 大余县| 双柏县| 满洲里市| 三台县| 庆安县| 永丰县| 潢川县| 永靖县| 镇巴县| 托里县| 镇康县| 申扎县| 合水县| 曲麻莱县| 赞皇县| 称多县| 昌宁县| 岑溪市| 独山县| 汝南县| 赤城县| 隆林| 大冶市| 临城县|