前言:
某個項目,開發過程中需要連接多個數據源,多數據源部分就不說了,在Spring Boot中其實就是手動構造不同的 datasource交給IOC容器,然後根據持久層框架 Mabatis 或者是 JPA之類的,明確下 數據源和持久層的綁定關係即可,直白說就是 調某個方法時用對應的數據源即可。
因爲,項目中主要都是數據庫的查詢,而且,前端頁面的設計,會在某個頁面同時訪問多個接口,緩存沒有的情況下,會導致蠻多數據庫操作,涉及 多個線程 操作 一個或者多個數據源。
自然想到:用連接池的方式,類似於線程池,複用連接,節省創建和回收的開銷,縮短響應時間。
於是,網上一番調研,首先吸引我注意力的是 Druid,網上資料很多,不贅述。
Druid使用時遇到的問題:
連接數據庫: Oracle (懷疑有可能是數據庫配置問題,但是數據庫在第三方,無法操作。。。)
使用版本:1.1.5
配置均爲常規配置: testOnBorrow 爲 false removeAbandoned 爲 false
問題:日誌經常打印出如下異常:
com.alibaba.druid.util.JdbcUtils - close statement error
java.sql.SQLRecoverableException: 關閉的連接
com.alibaba.druid.util.JdbcUtils - close connection error
java.sql.SQLRecoverableException: 無法從套接字讀取更多的數據
com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 10, active 0, maxActive xxx
使用此版本,服務上線之後,幾十分鐘便不可訪問,需要重啓才行。
問題猜測:可能存在連接泄露的情況,於是加入 超時強制回收配置如下
當有線程超時持有連接時,強制回收,並打印日誌信息。
加入此配置之後,服務可一直運行,查日誌時,有 超時強制回收的日誌打印出來,但是對應到具體的代碼行,就是個 簡單查詢的SQL,執行時間較短,不清楚因爲什麼導致了 連接泄露。
換用新版本:逛着逛着逛到了Druid 的 GitHub,立馬注意到有了新的版本:1.1.14. 升級版本,重新運行。 這次的情況是,異常還是會報,但是在 不配置超時強制回收(abandon相關選項)的情況下,服務也不會無故進入不可用的情況了。
最後策略:一直拋異常也是扎心了,設置超時強制回收也不是長久之計,遂決定換個數據庫連接池。
換用 Hikari連接池:
參考這篇文章:https://blog.csdn.net/bjweimengshu/article/details/80212290
換了 Hikari,配置比 Druid簡單點,服務上線後正常運行,到寫這邊Blog時,除了數據庫語法異常外,沒有出現其他的問題。
總結:
感覺問題不一定在 Druid,因爲只有 Oracle有這個問題,其他的 Mysql和SQLServer 均未出現問題,這個以後有機會得拿Oracle再測試下。
性能方面 說下自己用了兩個連接池的不嚴謹的感覺,沒有測試過自己的服務,也可能是心理原因,前端頁面感知上,用 Hikari的時候 響應會迅速些,大部分在可接受的範圍內。
總之,後面有機會再深入研究下。
2019年3月5日 追加:
被服務無故下線搞得有點敏感,經常打開頁面查看響應情況 以及查看error日誌,截止目前 並沒有拋出數據庫連接方面的異常,而且 可能因爲熱點代碼被即時編譯的原因,業務端感知服務性能提升了。