1. 程式人生 > >Java Mysql連線池配置和案例分析--超時異常和處理

Java Mysql連線池配置和案例分析--超時異常和處理

前言:
  最近在開發服務的時候, 發現服務只要一段時間不用, 下次首次訪問總是失敗. 該問題影響雖不大, 但終究影響使用者體驗. 觀察日誌後發現, mysql連線因長時間空閒而被關閉, 使用時沒有死鏈檢測機制, 導致sql執行失敗.
  問題的表層根源, 看似簡單, 但實際解決之路, 卻顯得有些曲折坎坷. 因此有必須分析下本質的原因, 以及Java Mysql連線池的處理策略和相關的配置項.

異常現象和問題本源:
  服務的持久層依賴mysql, 採用連線池的機制來優化效能. 但服務空閒一段時間(切確地講是mysql connection空閒一段時間), 下次使用時執行sql失敗.
  具體的異常, 可反映到具體的異常日誌:
  


  當然除了異常的原因以外, 裡面也提供了一個解決方案.  

1 2 3 4 5 6 com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 47,302,202 milliseconds ago.  The last packet sent successfully to the server was 47,302,202 milliseconds ago. is longer than the server configured value of 
'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem. 

  暫且不管這個autoReconnect=true

的解決方案是否有效, 我們來分析下問題本質.
  Mysql程序對擁有的資源, 都有其相應的回收策略. 比如空閒連線, 超過一段時間間隔後, mysql就會主動關閉該連線. 而這個時間間隔就由wait_timeoutinteractive_timeout來確定.
  Mysql伺服器關閉該空閒連線後,而客戶端的連線並沒有主動去關閉,導致首次使用時,執行失敗.
  順便談談mysql裡面涉及的兩個概念: 互動式連線和非互動式連線. 
  網上爭議和吐槽都很多, 但從官網的解讀來看, 或許只是mysql_real_connect()呼叫時, 是否開啟CLIENT_INTERACTIVE開關. 再深入的區別解讀, 或許已經沒有意義了.
  互動式連線, 由interactive_timeout來確定, mysql的命令列工具即是該型別
  非互動式連線, 則由wait_timeout來決定, jdbc/odbc等方式的連線即為該型別, 一般而言, Java Mysql連線池屬於該類別,需關注wait_timeout項.

曲折的路途:
  先後採用兩種方式,一種是設定重連選項,另一種是連線池主動淘汰.
  • 設定重連選項
  按照異常中附帶的建議,再jdbc的url中添加了屬性autoReconnect=true.
  原本以為妥妥的,沒想到事與願違, 還是出現了類似的錯誤.
  參照網上革命戰友的說法, mysql5以後autoReconnet=true已經失效了, 具體可以參考Bug #5020
  • 連線池主動淘汰
  在配置的連線池中,按一定的規則淘汰掉空閒連線,降低死鏈被使用的概率.
  1). testBeforeUse/testAfterUse
  testBeforeUse顧名思義, 就是把連線從連線池中取出時, 先執行validation sql,再執行目標的sql語句. testAfterUse則剛好相反,再放回連線池時進行檢測.
  雖然每次執行,都會額外的執行一次validation sql,但還是完美的解決上述的問題。不過需要注意的是,其代價昂貴,在高併發情況下需慎用.
  2). 定時任務+按空閒閾值淘汰
  按一定時間間隔執行清理任務,設定空閒時間的上限,一旦檢測到連線其空閒時間超過該閾值,則主動關閉掉. 當然定時週期和空閒閾值都小於wait_timeout值.
  3). 定時任務+validation sql檢測淘汰
  按一定時間間隔執行清理任務,對空閒連線進行validation sql檢測, 若失敗則主動關閉. 這種方式是testBeforeUse/testAfterUse的有益補充, 有效減少了執行validation sql的次數,解決了代價高昂的窘境. 當然定時週期小於wait_timeout值.

DBCP舉例:
  我們選用DBCP作為連線池配置的樣例, 看看它如何實現上述談到的主動淘汰策略的.
  先來看下DBCP關於空閒連線處理的配置項:

validationQuery SQL查詢,用來驗證從連線池取出的連線,在將連線返回給呼叫者之前.如果指定,則查詢必須是一個SQL SELECT並且必須返回至少一行記錄
testOnBorrow true 指明是否在從池中取出連線前進行檢驗,如果檢驗失敗,則從池中去除連線並嘗試取出另一個.注意: 設定為true後如果要生效,validationQuery引數必須設定為非空字串
testOnReturn false 指明是否在歸還到池中前進行檢驗注意: 設定為true後如果要生效,validationQuery引數必須設定為非空字串
testWhileIdle false 指明連線是否被空閒連接回收器(如果有)進行檢驗.如果檢測失敗,則連線將被從池中去除.注意: 設定為true後如果要生效,validationQuery引數必須設定為非空字串
timeBetweenEvictionRunsMillis -1 在空閒連接回收器執行緒執行期間休眠的時間值,以毫秒為單位. 如果設定為非正數,則不執行空閒連接回收器執行緒
numTestsPerEvictionRun 3 在每次空閒連接回收器執行緒(如果有)執行時檢查的連線數量
minEvictableIdleTimeMillis 1000 * 60 * 30 連線在池中保持空閒而不被空閒連接回收器執行緒(如果有)回收的最小時間值,單位毫秒

  注:如果想看更多DBCP的配置項, 請參考博文: DBCP的引數配置
  1). testBeforeUse/testAfterUse

1 2 3 4 5 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"     destroy-method="close">   <property name="testOnBorrow" value="true" />   <property name="testOnReturn" value="false" /> </bean>

  2). 定時任務+按空閒閾值淘汰

1 2 3 4 5 6 7 8 9 10 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"     destroy-method="close"> <!-- validation query -->   <property name="validationQuery" value="SELECT 1" /> <!-- 定時週期間隔 -->   <property name="timeBetweenEvictionRunsMillis" value="90000" />   <property name="numTestsPerEvictionRun" value="3" /> <!-- 空閒連線的生存閾值 -->   <property name="minEvictableIdleTimeMillis" value="1800000" />  </bean>  

  3). 定時任務+validation sql檢測淘汰

1 2 3 4 5 6 7 8 9 10 11 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"     destroy-method="close"> <!-- validation query -->   <property name="validationQuery" value="SELECT 1" /> <!-- 定時週期間隔 -->   <property name="timeBetweenEvictionRunsMillis" value="900000" />   <property 

相關推薦

Java Mysql連線配置案例分析--超時異常處理

前言:   最近在開發服務的時候, 發現服務只要一段時間不用, 下次首次訪問總是失敗. 該問題影響雖不大, 但終究影響使用者體驗. 觀察日誌後發現, mysql連線因長時間空閒而被關閉, 使用時沒有死鏈檢測機制, 導致sql執行失敗.   問題的表層根源, 看似簡單, 但實際解決之路, 卻顯得有些曲折坎坷

java資料庫連線配置的幾種方法

一,Tomcat配置資料來源: 方式一:在WebRoot下面建資料夾META-INF,裡面建一個檔案context.xml,內容如下:  <Context>       <Resource name="jdbc/test" auth="Container" type="javax.sq

java mysql連線【初學】

為什麼要用連線池 資料庫連線池負責分配、管理和釋放資料庫連線,它允許應用程式重複使用一個現有的資料庫連線,而不是再重新建立一個;釋放空閒時間超過最大空閒時間的資料庫連線來避免因為沒有釋放資料庫連線而引起的資料庫連線遺漏。這項技術能明顯提高對資料庫操作的效能。

Java技術學習筆記:過濾器鏈的實現方法、配置案例分析

今天給大家分享的是Java技術學習筆記:過濾器鏈的實現方法、配置和案例分析。 過濾器能夠對網站中的各種內容進行過濾(頁面、Servlet、圖片、檔案),可以在網站內容請求和響應時進行一些操作,完成一些通用的功能。 過濾器鏈 在專案中可以建立多個過濾器,網站內容可能會經過多個過濾器,多個過濾器就形成了過濾

1112_maven專案使用Druid連線配置步驟注意事項[mysql資料庫]

maven專案使用Druid連線池配置步驟和注意事項[mysql資料庫] 2018年06月13日 17:09:25 個人分類: java 注:這兩天搭建專案時,使用Druid連線池入了不少坑;以此記錄; MySQL Server 5.7.21 + mysql-connector-j

java技術學習總結:過濾器鏈的實現方法、配置案例分析

今天給大家分享的是Java技術學習總結:過濾器鏈的實現方法、配置和案例分析。 過濾器能夠對網站中的各種內容進行過濾(頁面、Servlet、圖片、檔案),可以在網站內容請求和響應時進行一些操作,完成一些通用的功能。 過濾器鏈 在專案中可以建立多個過濾器,網站內容可能會經過多個過濾器,多個過

HikariCP 的Java資料庫連線介紹及配置

HiKariCP是資料庫連線池的一個後起之秀,號稱效能最好,可以完美地PK掉其他連線池。 原文地址:http://blog.csdn.net/clementad/article/details/46928621 官網:https://github.com/brettwooldridge/Hi

java專案使用redis / 連線配置

1. pom                   <dependency>     <groupId>

【jmeter】jmeter連線mysql資料配置

目錄 一、資料庫mysql準備 資料庫IP 資料庫使用者名稱 資料庫密碼 二、jmeter配置 (1)測試計劃-新增-執行緒組,如下圖所示: (2)配置jdbc連線設定,選擇執行緒組-新增-配置元件-JDBC Connection  Con

2 使用Java讀取外部資原始檔,連線配置

1 外部資原始檔 jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.username=root jdbc.password=123456 jdbc.url=jdbc:mysql://127.0.0.1:3306/ma

Hibernate使用Tomcat配置Mysql連線

一個tomcat下的Hibernate程式`總是用不了幾天就掛`` 就試著做個連線池用``` 下面是我的步驟`: 1: 為Tomcat裝administration tools`` 第一步,確認你的Tomcat 中是否已安裝了Administration We

主流Java資料庫連線比較與開發配置實戰

1.資料庫連線池概述 資料庫連線的建立是一種耗時、效能低、代價高的操作,頻繁的資料庫連線的建立和關閉極大的影響了系統的效能。資料庫連線池是系統初始化過程中建立一定數量的資料庫連線放於連線池中,當程式需要訪問資料庫時,不再建立一個新的連線,而是從連線池中取出一個已建立的空

【最近面試遇到的一些問題】資料庫連線的優點原理,常用的java開源連線元件

資料庫連線是一種關鍵的有限的昂貴的資源,這一點在多使用者的網頁應用程式中體現得尤為突出。對資料庫連線的管理能顯著影響到整個應用程式的伸縮性和健壯性,影響到程式的效能指標。資料庫連線池正是針對這個問題提出來的。資料庫連線池負責分配、管理和釋放資料庫連線,它允許應用程式重複使用

為什麼HikariCP被號稱為效能最好的Java資料庫連線,如何配置使用

HiKariCP是資料庫連線池的一個後起之秀,號稱效能最好,可以完美地PK掉其他連線池。 什麼?不是有C3P0/DBCP這些成熟的資料庫連線池嗎?一直用的好好的,為什麼又搞出一個BoneCP來?因為,傳說中BoneCP在快速這個特點上做到了極致,官方資料是C3P0等

Java資料庫連線比較(c3p0,dbcp,proxoolBoneCP)

詳見:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp21 Java框架資料庫連線池比較(c3p0,dbcp和proxool,BoneC) 現在常用的開源資料連線池主要有c3p0,dbcp,proxool

spring-hibernate配置多個mysql連線

<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns

Java資料庫連線細節探討

我們知道,資料庫連線池可以把資料庫的連線快取起來,下次使用的話可以直接取到快取起來的資料庫連線。那麼,在這個過程中有幾個細節需要注意: 1、資料庫的連線數有沒有限制? 2、資料庫會不會自動斷開已經建立的連線? 3、如果資料庫重啟了,但應用沒有重啟,那麼資料庫連線池中的所有連線都不可用了,

weblogic伺服器連線配置細節

進入某個連線池配置頁,進入“連線“頁,點選高階選項的”show“顯示高階選項。 指定 "測試頻率" 並啟用 "測試保留的連線"、"測試建立的連線" 和 "測試釋放的連線"。   測試頻率(Test Frequency):  

MySQL SYS CPU高的案例分析(二)

原文: MySQL SYS CPU高的案例分析(二) 後面又做了補充測試,增加了每秒context switch的監控,以及SQL執行時各步驟消耗時間的監控。   【測試現象一】 啟用1000個併發執行緒的壓測程式,保持壓測程式持續執行,保持innodb_spin_wait_delay預設值

MySQL SYS CPU高的案例分析(一)

原文: MySQL SYS CPU高的案例分析(一) 【現象】 最近關注MySQL CPU告警的問題時,發現有一種場景,有一些伺服器最近都較頻繁的出現CPU告警,其中的現象是 SYS CPU佔比較高。 下面的截圖來源於“MySQL CPU報警”採集的檔案     【問題分析】