springboot hikari数据库连接池死链 出现异常
生活随笔
收集整理的這篇文章主要介紹了
springboot hikari数据库连接池死链 出现异常
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最近系統間歇性很慢,比如登錄,經常超時、無反應,查看log出現下述兩種異常,
異常情況1
異常情況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数据库连接池死链 出现异常的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql基础命令语句以及使用方法:
- 下一篇: java操作.ini文件