使用Mybatis時請注意這兩個參數,否則會讓你的數據庫連接爆掉


回去認真讀了Mybatis源碼,發現自己錯了,特此更正,以免誤導讀者,實在是對不起。其實poolMaximumActiveConnections的存在可以正確地限制數據庫連接池並發訪問數據的連接數,沒有問題,之所以我的數據庫爆掉了,是我沒有正確地維持SqlSessionFactory這個類的一個單例。在使用時一定要保持一個全局唯一的SqlSessionFactory 
     上次發帖是在跳槽后,今天為止已經在新公司工作了兩個星期了,感受什么的,我另外寫文章再談,言歸正傳,講正事~~! 
     目前正在開發一個產品的服務器端代碼,持久層我選擇了Mybatis3(也就是原來的ibatis)作為框架,之所以選擇他理由就是我覺得Hibernate搞起來貌似很復雜,我不太會用,哈哈(上家公司留下的陰影,用Hibernate搞得我想死)。上周完成了大部分代碼的開發工作,想着既然是要發布的產品,於是找來Jmeter做壓力測試,結果這一測,暴露問題了,mysql返回"too many connections"這個error,這個error的具體解釋參照這個鏈接http://dev.mysql.com/doc//refman/5.5/en/too-many-connections.html。 
     一般持久層與數據庫連接都會通過一個連接池(pooled datasource)管理,方便復用連接,控制並發,比較有名的有DBCP,C3P0,BONECP等等。Mybatis3自己實現了一個連接池,在配置文件中指定datasource的type屬性為POOLED即可使用。與並發關系較大的兩個Mybatis連接池參數是poolMaximumActiveConnections和poolMaximumIdleConnections。 
      好了,出了問題,自然得找文檔(官方手冊,中英文皆有),poolMaximumActiveConnections是最大的活動連接數,活動連接,顧名思義,就是正在與數據庫交互的連接,默認是10,poolMaximumIdleConnections是空閑連接數,就是沒有處理請求的連接,默認是5。Mysql的max_connections我設置的是200,既最大連接數。這樣一看,好像找不到問題所在,連接池最大的活動連接也就是10,跟200比還差很遠,Mysql怎么會返回"too many connections"呢?在查閱文檔無果后,我請教周圍的一位同事,他雖然沒用過Mybatis,但是他說是不是請求數超過poolMaximumActiveConnections后mybatis還會去獲取連接,是不是有這樣的參數控制,然后讓我看看源碼,說開源的東西嘛,搞不清楚就看源碼。 
      我一向對源碼抱有恐懼的心理,感覺那都是大神寫的,我等屌絲怎能看得懂,不過被逼無奈,翻出Mybatis的源碼看了一看,結果豁然開朗。找到org.apache.ibatis.datasource.pooled包下面的PooledDataSource類,這個就是連接池的實現類。可以看到里面定義了幾個參數,其中就包括poolMaximumActiveConnections和poolMaximumIdleConnections,找到pushConnection方法,這個方法里會判斷當前空閑連接數和poolMaximumIdleConnections的大小,如果小於他,會new PooledConnection並放進隊列中,這就導致一個問題,當所有的連接被占滿后,Mybatis為了保持一定的空閑連接,會不斷獲取新的連接,然后這些新連接被占用后,就會再去new PooledConnection,結果就是超過了mysql設置的最大連接數,然后數據庫返回該錯誤。不知道這算不算是Mybatis的一個"坑"吧,總之在使用時要小心了,並發量大的時候就會爆掉你的數據庫,解決辦法很簡單,將poolMaximumIdleConnections設置為0即可,果然改掉后壓力測試不會爆掉數據庫。 
       現在回想起來,官方文檔對poolMaximumIdleConnections的定義是:在任意時間存在的空閑連接數,完全就解釋了這個參數的含義,只不過當時沒有仔細想,那這個參數是不是該改名字叫poolPermanentIdleConnections比較好呢,呵呵。 
問題解決了,很開心,晚上回去再仔細讀下里面的源碼,看看還有沒有別的沒發現的問題。看來源碼也不是想象中的那么神秘和高深啊。其實為什么那個同事一下就能看出問題的大概,一方面是經驗豐富,另一方面可能與他理解數據庫連接池機制有關,歸根到底,基礎的東西還是最重要的。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM