日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

springboot hikari数据库连接池死链 出现异常

發布時間:2023/12/16 数据库 71 豆豆
生活随笔 收集整理的這篇文章主要介紹了 springboot hikari数据库连接池死链 出现异常 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近系統間歇性很慢,比如登錄,經常超時、無反應,查看log出現下述兩種異常,
異常情況1

The last packet successfully received from the server was 995,202 milliseconds ago. The last packet sent successfully to the server was 995,202 milliseconds ago.at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174)at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64)at com.mysql.cj.jdbc.ConnectionImpl.setAutoCommit(ConnectionImpl.java:2056)at com.zaxxer.hikari.pool.ProxyConnection.setAutoCommit(ProxyConnection.java:388)at com.zaxxer.hikari.pool.HikariProxyConnection.setAutoCommit(HikariProxyConnection.java)at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:284)... 44 common frames omitted

異常情況2

Caused by: java.sql.SQLNonTransientConnectionException: No operations allowed after connection closed.at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:110)at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:73)at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:73)at com.mysql.cj.jdbc.ConnectionImpl.setNetworkTimeout(ConnectionImpl.java:2490)at com.zaxxer.hikari.pool.PoolBase.setNetworkTimeout(PoolBase.java:550)at com.zaxxer.hikari.pool.PoolBase.isConnectionAlive(PoolBase.java:165)at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:179)... 30 common frames omitted

懷疑數據庫鏈接存在死鏈,后端是springboot使用的默認數據庫連接池hikari,配置如下

spring:datasource:driver: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://x.x.x.x:3306/dbname?useUnicode=true&characterEncoding=utf-8username: xxpassword: xxxxhikari:maximumPoolSize: 20maxLifetime: 60000minimumIdle: 10connectionTestQuery: SELECT 'x'

查看源碼得知,com.zaxxer.hikari.pool.HikariPool#getConnection(long)獲取連接時,判斷連接是否存活,

com.zaxxer.hikari.pool.PoolBase#isConnectionAlive boolean isConnectionAlive(final Connection connection)try {setNetworkTimeout(connection, validationTimeout);final int validationSeconds = (int) Math.max(1000L, validationTimeout) / 1000;//如果不配置connectionTestQuery,才會使用jdbc校驗機制if (isUseJdbc4Validation) {return connection.isValid(validationSeconds);}} com.zaxxer.hikari.pool.PoolBase#PoolBasePoolBase(final HikariConfig config){this.config = config;this.isUseJdbc4Validation = config.getConnectionTestQuery() == null;}com.mysql.cj.jdbc.ConnectionImpl#isValidpublic boolean isValid(int timeout) throws SQLException {//發送心跳包pingInternal(false, timeout * 1000);return true;}

繼續往下跟到了com.mysql.cj.protocol.a.NativeProtocol#sendCommand

public final NativePacketPayload sendCommand(Message queryPacket, boolean skipCheck, int timeoutMillis) {//發送心跳包,debug得知發送的十六進制0x0e,也就是數字14send(queryPacket, queryPacket.getPosition());}

總結

至此真相大白,因為配置了connectionTestQuery,所以沒有使用jdbc的校驗機制,修改方法就是去掉connectionTestQuery,jdbc的校驗機制是在獲取連接時,校驗合法性,比定時校驗效率要高;
另外,jdbc的校驗相比上層庫校驗效率更高,因為是tcp層的心跳包而不是mysql引擎解析的sql語句,所以druid、hikari層的校驗可以去掉了。

個人公眾號

總結

以上是生活随笔為你收集整理的springboot hikari数据库连接池死链 出现异常的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。