###1、源起 同事在調試程序時遇到了Mysql異常 com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:Communications link failure Last packet sent to the server was X ms ago ###2、分析 這是因爲JDBC客戶端的mysql鏈接在長時間不活動以後斷開了,斷開以後的首次請求會拋出這個異常。查詢mysql超時設置:show variables like ‘%timeout%’,查看和鏈接時間有關的MySQL系統變量,獲得以下結果:mysql
他的一個查詢程序跑了148秒,在同一個事務裏再執行update操做時,程序拋出了上面的異常。 一開始我覺得是在這個查詢執行時間過長,mysql主動切斷了鏈接。可是很奇怪的是在navicat單獨執行這個sql,五六秒就能獲得結果,雖然也很慢,可是沒那麼離譜。 這時候我懷疑,是否是結果在程序中早就查出來了,可是因爲程序自己的緣由,致使總的執行時間超過了wait_timeout設置的值,致使mysql server端切斷了不活動的鏈接。 在驗證這個問題時,因爲同事的maven依賴不少,致使依賴關係很是亂。日誌用的是log4j2,可是mvn dependency:tree查看到了不少log4j-1.二、slf4j各類橋接的依賴,不少都是因爲依賴dubbo暴露接口打成的jar包,而造成的間接依賴。在作了一些列exclusion後,終於能看到全面的日誌。以後就發現了log4jdbc打印的不少的ResultSet日誌:sql
這個sql查詢到了9K+的結果,這個resultset日誌打了大概2W行,能夠看到是log4jdbc配置問題致使程序在獲取ResultSet後浪費了大量的時間進行結果分析和日誌記錄,致使mysql鏈接超時。 ###3、解決 因爲項目自己用的是druid和Mybatis,都具備日誌打印的功能,對於log4jdbc的需求其實很小,就把log4jdbc去掉了。問題解決。 ###4、總結 若是不對錶象進行分析,很難真正的解決問題。日誌對於程序調試仍是尤爲重要的。另外wait_timeout的值太小,是否會引發druid鏈接池在鏈接空閒時,老是從新獲取鏈接,這個問題回頭再議。maven