Timeout: Pool empty. Unable to fetch a connection in 30 seconds, none available[size:200; busy:200; idle:0; lastwait:30000]

這個(gè)問(wèn)題之前在項(xiàng)目中就困擾了我很多次,只不過(guò)重新部署就好了而且再也沒(méi)有出現(xiàn)過(guò)了,所以也就沒(méi)注意。但是今天這個(gè)問(wèn)題一直出現(xiàn),重新部署運(yùn)行一會(huì)兒就出現(xiàn),運(yùn)行一會(huì)就出現(xiàn)。不知道怎么弄,沒(méi)辦法就硬著頭皮上網(wǎng)搜,花了一天時(shí)間,也算是把這奇葩的BUG解決了,這里記錄一下解決的幾個(gè)過(guò)程。
首先講一下場(chǎng)景,項(xiàng)目是一個(gè)物聯(lián)網(wǎng)項(xiàng)目,會(huì)有硬件向服務(wù)器上報(bào)信息,硬件數(shù)量多,上傳頻率高,上來(lái)的數(shù)據(jù)需要做處理,在這種高并發(fā)的環(huán)境下,我先是盡可能不去數(shù)據(jù)庫(kù)取數(shù)據(jù),但是無(wú)可避免的還是會(huì)需要訪問(wèn)到數(shù)據(jù)庫(kù),退無(wú)可退了,只能開(kāi)始找原因了。
故障的意思很簡(jiǎn)單直接,就是說(shuō)數(shù)據(jù)庫(kù)的連接池空了,在超時(shí)時(shí)限內(nèi)沒(méi)有獲取到連接,則拋出異常,于是去數(shù)據(jù)庫(kù)查看連接

Mysql -> show full processlist;

通過(guò)這句話在MySQL中去獲取所有進(jìn)程,看看自己這個(gè)項(xiàng)目的進(jìn)程,確實(shí)有很多,而且在Command這一欄還都是sleep,想來(lái)可能跟這個(gè)有關(guān)系,于是乎上網(wǎng)搜相關(guān)內(nèi)容,搜來(lái)的大致意思是連接沒(méi)有正確關(guān)閉。不過(guò)我代碼里面用到的SQL是關(guān)閉了的,雖然體感是這個(gè)問(wèn)題,但是從這入手應(yīng)該是解決不了問(wèn)題。
但是關(guān)于這個(gè)sleep的問(wèn)題,又引申到了MySQL的wait_timeout和interactive_timeout的這兩個(gè)屬性,這兩個(gè)都是空閑連接的超時(shí)時(shí)間,只不過(guò)前者是非交互式連接的(通過(guò)jdbc連接),后者是交互式連接的(通過(guò)MySQL客戶端連接)。于是嘗試設(shè)置一下wait_timeout的時(shí)間,這里默認(rèn)設(shè)置的是8h

Mysql -> set global wait_timeout=30;

設(shè)置成30s之后,重新部署,跑起來(lái)之后確實(shí)是有效的,那些sleep的進(jìn)程都消失了,感覺(jué)好像這樣就OK了,但是接下來(lái)又報(bào)了另外一個(gè)異常,具體異常忘記記錄了,大致意思是連接丟失,上網(wǎng)搜一下發(fā)現(xiàn)時(shí)wait_timeout時(shí)間設(shè)置太短造成的。所以感覺(jué)修改wait_timeout的時(shí)間不是正確的解,于是又重新設(shè)置成了8H,再?gòu)膭e的地方入手。
這條異常記錄上有提到size是100,于是乎想到提高最大連接量試試(其實(shí)這是個(gè)很笨的主意,因?yàn)?00能超,1000估計(jì)都一樣超,時(shí)間問(wèn)題而已)。這就又涉及到了Tomcat-jdbc連接池的配置,但是之前我試著去配置連接池,想讓最大連接量能大一些,只不過(guò)沒(méi)有用,先貼一下原先的配置,由于是spring-boot項(xiàng)目,所以配置是寫在properties里面

#連接池最大連接數(shù)
spring.datasource.tomcat.max-active=200
#空閑池中最大連接數(shù)
spring.datasource.tomcat.max-idle=50
#空閑池中最小連接數(shù)
spring.datasource.tomcat.min-idle=10
spring.datasource.tomcat.initial-size=10

本意是想讓連接池的連接數(shù)變成200的,但是不起作用,stackoverflow上看是說(shuō)spring-boot的1.4.1版本有一個(gè)更改,本來(lái)是spring.datasource.max-active=200的,現(xiàn)在得要根據(jù)具體情況來(lái)調(diào)整,比如用Tomact就是spring.datasource.tomcat.max-active=200。只不過(guò)我是1.4.3版本,我以為是向上兼容,沒(méi)想到居然是向下兼容,改為不帶Tomcat的就可以了,加上又看了一下連接池的配置,最終連接池的配置版本為

#連接池最大連接數(shù)
spring.datasource.max-active=200
#空閑池中最大連接數(shù)
spring.datasource.max-idle=50
#空閑池中最小連接數(shù)
spring.datasource.min-idle=10
spring.datasource.initial-size=10
#連接在池中空閑最小時(shí)間后被清除
spring.datasource.min-evictable-idle-time-millis=60000
#隔多久時(shí)間清回收廢棄連接
spring.datasource.time-between-eviction-runs-millis=30000
#每次調(diào)用檢測(cè)池里連接的可用性,假如連接池中的連接被數(shù)據(jù)庫(kù)關(guān)閉了,應(yīng)用通過(guò)連接池getConnection時(shí)會(huì)重新創(chuàng)建
spring.datasource.testOnBorrow=true
spring.datasource.validation-query=SELECT 1
#移除被遺棄的連接
spring.datasource.remove-abandoned=true
#設(shè)置超時(shí)時(shí)間
spring.datasource.tomcat.remove-abandoned-timeout=60

不得不說(shuō),在高并發(fā)的應(yīng)用環(huán)境下,連接池的配置是真的重要,關(guān)于連接池的配置我感覺(jué)可以另開(kāi)一篇來(lái)介紹了。最下面兩個(gè)就是確實(shí)解決掉這個(gè)BUG所需要的配置,注釋也稍微寫了一下,是移除被遺棄的連接,超過(guò)60秒就被判斷為遺棄的連接。這里的遺棄的連接就是在代碼過(guò)程中寫的比如沒(méi)有及時(shí)關(guān)閉的連接之類的糟糕的寫法。其實(shí)針對(duì)這個(gè)問(wèn)題,體感上來(lái)說(shuō)也確實(shí)是這么回事,連接用完之后,超過(guò)一個(gè)設(shè)定的時(shí)間就自動(dòng)刪掉。這點(diǎn)有點(diǎn)像Java線程池框架中的Executors.newCachedThreadPool(),設(shè)定的是線程存活60秒就自動(dòng)刪掉,之前試過(guò)在60秒之內(nèi)瘋狂增加線程數(shù),并將線程數(shù)設(shè)定的比較小,一段時(shí)間后就報(bào)錯(cuò)了,跟今天連接池的這種情況確實(shí)是很像。
大概就是這么個(gè)情況,僅僅提供一個(gè)結(jié)題思路,當(dāng)中還有不少繞路,也怪自己對(duì)連接池的配置還并不了解,如果一開(kāi)始就修改對(duì)連接池的配置的話,也不至于被這個(gè)BUG糾纏一整天了。

長(zhǎng)路漫漫。。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,569評(píng)論 19 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,275評(píng)論 6 342
  • application的配置屬性。 這些屬性是否生效取決于對(duì)應(yīng)的組件是否聲明為Spring應(yīng)用程序上下文里的Bea...
    新簽名閱讀 5,539評(píng)論 1 27
  • 自打七月初到中旬,每天的氣溫都不算太高,加上梅雨季節(jié)的影響,更加感覺(jué)到?jīng)鏊孢m。正欣喜著,如果一直都是以這樣的天...
    硯磊閱讀 387評(píng)論 0 0
  • $嘗試一個(gè)好玩的東西——怎樣在任何文章中學(xué)習(xí)畫畫?比如說(shuō),我剛剛閱讀了湯小小的這篇寫作技巧。我們來(lái)測(cè)試一下。 下圖...
    ALEX阿雷的小星球閱讀 820評(píng)論 0 5

友情鏈接更多精彩內(nèi)容