MySQL-CommunicationsException異常的三個(gè)典型場(chǎng)景及解決方法
我們?cè)谑褂肕ySQL數(shù)據(jù)庫(kù)的時(shí)候,偶爾會(huì)遇到com.mysql.jdbc.exceptions.jdbc4.CommunicationsException,為了以后能夠更快速的定位解決該問(wèn)題,下面對(duì)該異常出現(xiàn)的場(chǎng)景及解決方法進(jìn)行總結(jié),希望能起到拋磚引玉的作用。
場(chǎng)景一
場(chǎng)景描述
wait_timeout
根因分析
異常的原因是數(shù)據(jù)庫(kù)連接空閑時(shí)間超過(guò)了MySQL服務(wù)器配置的wait_timeout,即上圖中【2.3 數(shù)據(jù)庫(kù)操作】時(shí)候的時(shí)間 【減去】【1.5 放入連接池中】時(shí)候的時(shí)間【大于】wait_timeout。
解決辦法
方法一
mysql5以前的版本可以直接在jdbcurl的配置中附加上“autoReconnect=true”。
方法二
將mysql的全局變量wait_timeout的值修改為最大。
show global variables like "wait_timeout";
方法三【建議采納的方案】
目前項(xiàng)目采用的數(shù)據(jù)庫(kù)連接池是druid,解決該異常用到的配置項(xiàng)如下:
配置 | 缺省值 | 說(shuō)明 |
validationQuery | 用來(lái)檢測(cè)連接是否有效的sql,要求是一個(gè)查詢語(yǔ)句,常用select 'x'。如果validationQuery為null,testOnBorrow、testOnReturn、testWhileIdle都不會(huì)起作用。 | |
testWhileIdle | false | 建議配置為true,不影響性能,并且保證安全性。申請(qǐng)連接的時(shí)候檢測(cè),如果空閑時(shí)間大于 |
timeBetweenEvictionRunsMillis | 1分鐘 | 有兩個(gè)含義: |
minEvictableIdleTimeMillis | 連接保持空閑而不被驅(qū)逐的最小時(shí)間 |
場(chǎng)景二
場(chǎng)景描述
應(yīng)用阻塞無(wú)響應(yīng)
根因分析
客戶端發(fā)送select語(yǔ)句后,服務(wù)端往客戶端寫大量數(shù)據(jù),客戶端需要等待超過(guò)1分鐘才能繼續(xù)寫入,服務(wù)端就會(huì)把這種寫入時(shí)超過(guò)1分鐘(默認(rèn)值)等待的連接直接關(guān)閉。
而為什么會(huì)超過(guò)1分鐘?根因是jdbc程序在接收大量數(shù)據(jù)時(shí)會(huì)耗費(fèi)大量的cpu跟內(nèi)存資源,還需要不斷做的GC,導(dǎo)致接收暫停,一旦GC時(shí)間超過(guò)net_write_timeout,mysql則會(huì)關(guān)閉連接。
根因
解決辦法
方法一
根據(jù)業(yè)務(wù)場(chǎng)景增大net_write_timeout
SET GLOBAL net_write_timeout =180;
SELECT @@global.net_write_timeout ;
SELECT @@session.net_read_timeout ;
show variables like '%timeout%'
方法二【建議采納的方案】
根據(jù)業(yè)務(wù)場(chǎng)景,優(yōu)化應(yīng)用程序。
優(yōu)化方向:
- 優(yōu)化SQL,通過(guò)分頁(yè)的方式減少一次查詢返回的數(shù)據(jù)量
- 優(yōu)化應(yīng)用,減少應(yīng)用停頓時(shí)間
場(chǎng)景三
場(chǎng)景描述
SSL
問(wèn)題分析
MySQL server versions like 5.6.25 and earlier or 5.7.5 and earlier,客戶端連接屬性u(píng)seSSL默認(rèn)是false;MySQL server versions like 5.6.25+ or 5.7.5+,客戶端連接屬性u(píng)seSSL默認(rèn)是true。
默認(rèn)useSSL=true的MySQL server版本,客戶端連接屬性還需要配置其他額外的連接屬性,如果沒(méi)有配置會(huì)拋出CommunicationsException異常。
解決辦法
方法一
在不需要SSL連接的場(chǎng)景下,顯示設(shè)置useSSL=false
方法二
在需要SSL連接的場(chǎng)景下,客戶端和服務(wù)端都需要進(jìn)行正確的配置。
具體配置可以參考官網(wǎng)文檔:Connecting Securely Using SSL:https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-using-ssl.html