mysql報錯:Caused by: com.mysql.cj.exceptions.CJCommunicationsException: The last packet successfully received from the server was


Caused by: com.mysql.cj.exceptions.CJCommunicationsException: The last packet successfully received from the server was 35,813 milliseconds ago. The last packet sent successfully to the server was 35,813 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.

 

原因分析:

MySQL連接時,服務器默認的“wait_timeout”是8小時,也就是說一個connection空閑超過8個小時,Mysql將自動斷開該connection。connections如果空閑超過8小時,Mysql將其斷開,而DBCP連接池並不知道該connection已經失效,如果這時有Client請求connection,DBCP將該失效的Connection提供給Client,將會造成異常。

 

1,首先進入mysql,查看 wait_timeout、interactive_timeout這個值是否為默認的8小時(即 28800)

 

其中wait_timeout就是負責超時控制的變量,其時間為長度為28800s,就是8個小時,那么就是說MySQL的服務會在操作間隔8小時后斷開,需要再次重連。也有用戶在URL中使用jdbc.url=jdbc:mysql://localhost:3306/nd?autoReconnect=true來使得連接自動恢復,當然了,這是可以的,不過是MySQL4及其以下版本適用。MySQL5中已經無效了

 

解決方式一:修改msyql 配置 ,不推薦

解決方式二:保證應用在MySQL的’wait_timeout’時間內,至少訪問一次數據庫,配置文件增加心跳檢測部分

sys.db.initialSize=10
sys.db.maxIdle=50
sys.db.minIdle=5
sys.db.maxActive=50
sys.db.logAbandoned=true
sys.db.removeAbandoned=true
sys.db.removeAbandonedTimeout=120
sys.db.maxWait=60000
sys.db.type=mysql
dialect=MYSQL
sys.db.class=com.mysql.jdbc.Driver

sys.db.url=jdbc:mysql://localhost:3306/test?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8
sys.db.username=root
sys.db.password=123456

 

 

 

# 28800 8小時

# 21600 6小時

 

show variables like '%timeout%';

 

SET GLOBAL wait_timeout=21600;

SET wait_timeout=21600;

SHOW GLOBAL VARIABLES LIKE 'wait_timeout';

SHOW VARIABLES LIKE 'wait_timeout';

 

SET GLOBAL interactive_timeout=58800;

SET interactive_timeout=58800;

SHOW GLOBAL VARIABLES LIKE 'interactive_timeout';

SHOW VARIABLES LIKE 'interactive_timeout';

 

連接池內連接的生存周期(idleConnectionTestPeriod)小於數據庫中的wait_timeout的值

解決方式二:保證應用在MySQL的'wait_timeout'時間內,至少訪問一次數據庫,配置文件增加心跳檢測部分

 

 

timeBetweenEvictionRunsMillis: 20800 # 配置間隔多久才進行一次檢測 原值 :60000 改小與timeout時間.

idleConnectionTestPeriod: 20800 # 連接池內連接的生存周期(idleConnectionTestPeriod)小於數據庫中的wait_timeout的值

minEvictableIdleTimeMillis: 18000000 # 1000 * 60 * 30 =18000000 (默認值) 連接在池中保持空閑而不被空閑連接回收器線程,(如果有)回收的最小時間值,單位毫秒

 

durid配置:

timeBetweenEvictionRunsMillis: 20800 # 配置間隔多久才進行一次檢測 原值 :60000 改小與timeout時間.

idleConnectionTestPeriod: 20800 # 連接池內連接的生存周期(idleConnectionTestPeriod)小於數據庫中的wait_timeout的值

minEvictableIdleTimeMillis: 18000000 # 1000 * 60 * 30 =18000000 (默認值) 連接在池中保持空閑而不被空閑連接回收器線程,(如果有)回收的最小時間值,單位毫秒

 

<!-- 數據源定義 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName" value="${sys.db.class}"/>
		<property name="url" value="${sys.db.url}"/>
		<property name="username" value="${sys.db.username}"/>
		<property name="password" value="${sys.db.password}"/> 
		<property name="initialSize" value="${sys.db.initialSize}"/><!-- 初始化連接 -->
		<property name="maxIdle" value="${sys.db.maxIdle}"/><!-- 最大空閑連接 -->
		<property name="minIdle" value="${sys.db.minIdle}"/><!-- 最小空閑連接 -->
		<property name="maxActive" value="${sys.db.maxActive}"/><!-- 最大連接數量 -->
		<property name="logAbandoned" value="${sys.db.logAbandoned}"/><!-- 是否在自動回收超時連接的時候打印連接的超時錯誤 -->
		<property name="removeAbandoned" value="${sys.db.removeAbandoned}"/><!-- 是否自動回收超時連接 -->
		<property name="removeAbandonedTimeout" value="${sys.db.removeAbandonedTimeout}"/><!-- 超時時間(以秒數為單位) -->
		<property name="maxWait" value="${sys.db.maxWait}"/><!-- 超時等待時間以毫秒為單位 6000毫秒/1000等於60秒 -->
		
		
		<!-- sql 心跳檢測 -->
		<property name= "testWhileIdle" ><value>true</value></property><!-- 起了一個 異步Evict的TimerTask定時線程進行控制 定時對線程池中的鏈接進行validateObject校驗,對無效的鏈接進行關閉后,會調用ensureMinIdle,適當建立鏈接保證最小的minIdle連接數 -->
		<property name= "testOnBorrow" ><value>false</value></property><!-- 在進行borrowObject進行處理時,對拿到的connection進行validateObject校驗 -->
		<property name= "testOnReturn" ><value>false</value></property><!-- 進行returnObject對返回的connection進行validateObject校驗 -->
		<property name= "validationQuery" ><value>select 1</value></property><!-- 代表檢查的sql -->
		<property name= "validationQueryTimeout" ><value>1</value></property><!-- 代表在執行檢查時,通過statement設置,statement.setQueryTimeout(validationQueryTimeout) -->
		<property name= "timeBetweenEvictionRunsMillis" ><value>28700</value></property><!-- 設置的Evict線程的時間,多久檢查一次,建議小於mysql默認時間默認的8小時(即 28800秒),單位ms,大於0才會開啟evict檢查線程 -->
		<property name= "numTestsPerEvictionRun" ><value>${sys.db.maxActive}</value></property><!-- 代表每次檢查鏈接的數量,建議設置和maxActive一樣大,這樣每次可以有效檢查所有的鏈接. -->
		<property name= "minEvictableIdleTimeMillis"><value>18000000</value></property><!--  -->
		
	</bean>


免責聲明!

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



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