国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術文章
文章詳情頁

Spring Boot集成Druid出現異常報錯的原因及解決

瀏覽:3日期:2023-07-13 14:45:20
目錄Spring Boot集成Druid異常異常分析原理追蹤禁用Ping Method為什么要清空空閑60秒以上的連接Spring Boot集成Druid異常

在Spring Boot集成Druid項目中,發現錯誤日志中頻繁的出現如下錯誤信息:

discard long time none received connection. , jdbcUrl : jdbc:mysql://******?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8, version : 1.2.3, lastPacketReceivedIdleMillis : 172675

經過排查發現是Druid版本導致的異常,在1.2.2及以前版本并未出現如此異常。而在其以上版本均存在此問題,下面就來分析一下異常原因及解決方案。

異常分析

首先上面的異常并不影響程序的正常運行,但作為程序員看到程序中不停的出現異常還是難以忍受的。所以還是要刨根問底的解決一下的。

跟蹤堆棧信息會發現對應的異常是從com.alibaba.druid.pool.DruidAbstractDataSource#testConnectionInternal方法中拋出的,對應的代碼如下:

if (valid && isMySql) { // unexcepted branch long lastPacketReceivedTimeMs = MySqlUtils.getLastPacketReceivedTimeMs(conn); if (lastPacketReceivedTimeMs > 0) {long mysqlIdleMillis = currentTimeMillis - lastPacketReceivedTimeMs;if (lastPacketReceivedTimeMs > 0 //&& mysqlIdleMillis >= timeBetweenEvictionRunsMillis) { discardConnection(holder); String errorMsg = 'discard long time none received connection. ' + ', jdbcUrl : ' + jdbcUrl + ', jdbcUrl : ' + jdbcUrl + ', lastPacketReceivedIdleMillis : ' + mysqlIdleMillis; LOG.error(errorMsg); return false;} }}

上述代碼中,MySqlUtils.getLastPacketReceivedTimeMs(conn) 是獲取上一次使用的時間,mysqlIdleMillis 就是計算出來空閑的時間,timeBetweenEvictionRunsMillis 是常量60秒。如果連接空閑了60秒以上,那就discardConnection(holder) 丟棄這個舊連接并順帶打印了一個日志LOG.warn(errorMsg)。

原理追蹤

在上述代碼中,我們看到進入該業務邏輯是有前提條件的,也就是valid和isMySql變量同時為true。isMySql為true是必須的,我們使用的本身就是Mysql數據庫。那么是否可以讓valid為false呢?這樣不就不會進入該業務處理了嗎?

來看看valid的來源,還是在該方法的上面:

boolean valid = validConnectionChecker.isValidConnection(conn, validationQuery, validationQueryTimeout);

我們找到validConnectionChecker的Mysql實現子類MySqlValidConnectionChecker,該類中對isValidConnection的實現如下:

public boolean isValidConnection(Connection conn, String validateQuery, int validationQueryTimeout) throws Exception { if (conn.isClosed()) {return false; } if (usePingMethod) {if (conn instanceof DruidPooledConnection) { conn = ((DruidPooledConnection) conn).getConnection();}if (conn instanceof ConnectionProxy) { conn = ((ConnectionProxy) conn).getRawObject();}if (clazz.isAssignableFrom(conn.getClass())) { if (validationQueryTimeout <= 0) {validationQueryTimeout = DEFAULT_VALIDATION_QUERY_TIMEOUT; } try {ping.invoke(conn, true, validationQueryTimeout * 1000); } catch (InvocationTargetException e) {Throwable cause = e.getCause();if (cause instanceof SQLException) { throw (SQLException) cause;}throw e; } return true;} } String query = validateQuery; if (validateQuery == null || validateQuery.isEmpty()) {query = DEFAULT_VALIDATION_QUERY; } Statement stmt = null; ResultSet rs = null; try {stmt = conn.createStatement();if (validationQueryTimeout > 0) { stmt.setQueryTimeout(validationQueryTimeout);}rs = stmt.executeQuery(query);return true; } finally {JdbcUtils.close(rs);JdbcUtils.close(stmt); }}

我們可以看到上述方法中有三個返回的地方:第一個連接已關閉;第二個使用ping的形式進行檢查;第三,使用select 1的方式進行檢查。而使用ping的形式檢查時,無論是否拋異常都會返回true。這里我們禁用該模式即可。

進入ping的業務邏輯主要靠變量usePingMethod來判斷,追蹤代碼會發現在這里進行的設置:

public void configFromProperties(Properties properties) { String property = properties.getProperty('druid.mysql.usePingMethod'); if ('true'.equals(property)) {setUsePingMethod(true); } else if ('false'.equals(property)) {setUsePingMethod(false); }}

那么,也就是說,當我們把系統屬性druid.mysql.usePingMethod設置為false即可禁用該功能。

禁用Ping Method

找到了問題的根源,那么剩下的就是如何禁用了,通常有三種形式。

第一,在啟動程序時在運行參數中增加:-Ddruid.mysql.usePingMethod=false。

第二,在Spring Boot項目中,可在啟動類中添加如下靜態代碼快:

static { System.setProperty('druid.mysql.usePingMethod','false');}

第三,類文件配置。在項目的DruidConfig類中新增加:

/** 解決druid 日志報錯:discard long time none received connection:xxx* */@PostConstructpublic void setProperties(){ System.setProperty('druid.mysql.usePingMethod','false');}

至此,已可以成功關閉該功能,異常信息再也不會出現了。

為什么要清空空閑60秒以上的連接

猜測,阿里給數據庫設置的數據庫空閑等待時間是60秒,mysql數據庫到了空閑等待時間將關閉空閑的連接,以提升數據庫服務器的處理能力。

MySQL的默認空閑等待時間是8小時,就是「wait_timeout」的配置值。如果數據庫主動關閉了空閑的連接,而連接池并不知道,還在使用這個連接,就會產生異常。

以上就是Spring Boot集成Druid出現異常報錯的原因及解決的詳細內容,更多關于Spring Boot集成Druid出現異常的資料請關注好吧啦網其它相關文章!

標簽: Spring
相關文章:
主站蜘蛛池模板: 欧美视频在线一区二区三区 | 免费国内精品久久久久影院 | 国产成人免费手机在线观看视频 | 免费国产成人手机在线观看 | 久久网免费 | 国产精品视频永久免费播放 | 久久99国产亚洲高清观看韩国 | www久久com| 成人久久18免费游戏网站 | 99热久久精品国产 | 亚洲视频在线一区 | 91精品国产高清久久久久 | 91国内精品久久久久影院优播 | 日韩精品观看 | 岛国搬运工最新网地址 | 亚洲人妖女同在线播放 | 欧美性xxxx18 | 欧美成人免费在线视频 | 一级片美女 | 一区二区三区国产精品 | freesex寂寞老妇hd | 亚洲国产成人久久一区久久 | 国产在线精品观看一区 | 国产欧美另类久久精品91 | 亚洲综合精品成人 | 亚洲精品三级 | 日韩一级大片 | japanese日本舒服丰满 | 亚洲超大尺度激情啪啪人体 | 欧美做a一级视频免费观看 欧美做爱毛片 | a毛片在线还看免费网站 | 国产剧情一区二区 | 欧美激情特级黄aa毛片 | 成人国产精品免费网站 | 美女视频黄视大全视频免费网址 | 一区二区三区高清不卡 | 国产毛片在线高清视频 | 久久99久久精品国产99热 | 91视频天堂 | 国产精品久久九九 | 久草资源网站 |