用60個線程併發訪問某個讀和寫均有的業務接口,性能測試人員查看Oracle數據庫負載CPU很是高,並且oracle的Logons指標達到148.1次/秒(這個值的含義是數據庫客戶端登陸認證的每秒的次數)。 html
並且查看應用程序中的線程棧,也發現了較多數量的線程處於建立新的oracle物理鏈接處。 數據庫
這當時就讓我有點兒糊塗了,咱們不是用了鏈接池嗎?怎麼還會常常建立物理鏈接呢? apache
遇到這個問題,我當時也是從本身掌握的各類知識裏去想可能的緣由,都想到了是否是由於tcp鏈接的超時時間是否是過短,仔細一想這些可能性都排除掉了。而後查看鏈接池的配置,當時咱們的同窗告訴我這些配置跟線上的是同樣的,應該沒有問題,我當時是就懷疑是maxIdle設置過小致使的緣由,可是沒有什麼具體的依據。 安全
因此我就簡單開發了一個頁面能夠實時查看當時應用鏈接池的active number(當前被使用的數據庫鏈接數)和idle number(當前處於空閒狀態的數據庫鏈接數)。再次運行測試腳本,經過查看鏈接池的鏈接數就能夠看出來,鏈接數的波動較大,有時候鏈接總數(上面兩個數字相加)從20多忽然降到10,說明物理鏈接被銷燬了,建立了新的物理鏈接,那這就與咱們看到的一些異常現象相吻合了,建立新的鏈接就會致使oracle數據庫服務器的logons數量增長。因爲鏈接的複用率較差,致使頻繁的建立物理鏈接,oracle數據庫的資源消耗增大。 服務器
網上找到一篇文章詳細介紹dbcp鏈接池配置的,它關於maxIdle的配置說明是這麼寫的。 併發
maxIdle值與maxActive值應配置的接近。 由於,當鏈接數超過maxIdle值後,剛剛使用完的鏈接(剛剛空閒下來)會當即被銷燬。而不是我想要的空閒M秒後再銷燬起一個緩衝做用。這一點DBCP作的可能與你想像的不同。 若maxIdle與maxActive相差較大,在高負載的系統中會致使頻繁的建立、銷燬鏈接,鏈接數在maxIdle與maxActive間快速頻繁波動,這不是我想要的。 高負載系統的maxIdle值能夠設置爲與maxActive相同或設置爲-1(-1表示不限制),讓鏈接數量在minIdle與maxIdle間緩衝慢速波動。原文參考: http://elf8848.iteye.com/blog/1931778
看到這個我明白了由於咱們的配置是maxIdle配置的值是5,而maxActive配置的值爲40,這樣當併發較高的時候,當鏈接數接近maxActive值的狀況下,空閒鏈接數很容易超過maxIdle,很快就被鏈接池給主動銷燬了,這樣就致使了鏈接頻繁的建立,弱化了數據庫鏈接池的做用。 oracle
此次的性能測試然讓我深入的感覺到了數據庫鏈接池對的價值,使用得當,它可以很好地複用已有的物理鏈接,在高併發的場景下,減小頻繁的建立和銷燬物理鏈接,下降系統的壓力。用得很差,它的價值就發揮不出來,就像我們今天這個案例同樣。 tcp
maxIdle的值爲何要與maxActive的接近呢?果然如此嗎?咱們還要經過源碼來分析它背後的根本緣由。 高併發
看看上圖是對dbcp鏈接池的獲取和歸還鏈接對象的流程圖的描述,經過該圖咱們就一目瞭然了。 源碼分析
詳細的原理和源碼分析請看這裏:http://www.myexception.cn/apache/1874092.html
maxIdle值與maxActive值應配置的接近。
由於,當鏈接數超過maxIdle值後,剛剛使用完的鏈接(剛剛空閒下來)會當即被銷燬。而不是我想要的空閒M秒後再銷燬起一個緩衝做用。這一點DBCP作的可能與你想像的不同。
若maxIdle與maxActive相差較大,在高負載的系統中會致使頻繁的建立、銷燬鏈接,鏈接數在maxIdle與maxActive間快速頻繁波動,這不是咱們想要的。
高負載系統的maxIdle值能夠設置爲與maxActive相同或設置爲-1(-1表示不限制),讓鏈接數量在minIdle與maxIdle間緩衝慢速波動。多餘的空閒鏈接等待回收線程來緩慢回收。