我的应用程序正在使用tomcat JDBC连接池通过以下连接池配置连接到远程MySQL数据库,
maxActive: 80
maxWait: 60000
minIdle: 5
testOnBorrow: true
validationQuery: SELECT 1
validationInterval: 30000
validationQueryTimeout: 10
大多数情况下一切正常,但偶尔应用程序在连接池上执行 testOnBorrow 时似乎会卡住。这是通过启用Java Flight Recorder发现的,它显示了以下堆栈跟踪,
java.net.SocketInputStream.read(byte[], int, int, int)
java.net.SocketInputStream.read(byte[], int, int)
com.mysql.jdbc.util.ReadAheadInputStream.fill(int)
com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(byte[], int, int)
com.mysql.jdbc.util.ReadAheadInputStream.read(byte[], int, int)
com.mysql.jdbc.MysqlIO.readFully(InputStream, byte[], int, int
com.mysql.jdbc.MysqlIO.reuseAndReadPacket(Buffer, int)
com.mysql.jdbc.MysqlIO.reuseAndReadPacket(Buffer)
com.mysql.jdbc.MysqlIO.checkErrorPacket(int)
com.mysql.jdbc.MysqlIO.sendCommand(int, String, Buffer, boolean, String, int)
com.mysql.jdbc.MysqlIO.sqlQueryDirect(StatementImpl, String, String, Buffer, int, int, int, boolean, String, Field[])
com.mysql.jdbc.ConnectionImpl.execSQL(StatementImpl, String, int, Buffer, int, int, boolean, String, Field[], boolean)
com.mysql.jdbc.ConnectionImpl.execSQL(StatementImpl, String, int, Buffer, int, int, boolean, String, Field[])
com.mysql.jdbc.StatementImpl.execute(String, boolean)
com.mysql.jdbc.StatementImpl.execute(String)
org.apache.tomcat.jdbc.pool.PooledConnection.validate(int, String)
org.apache.tomcat.jdbc.pool.PooledConnection.validate(int)
org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(long, PooledConnection, String, String)
org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(int, String, String)
org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection()
因此上面的套接字读取发生在端口3306上的远程MySQL服务器上。套接字读取持续大约15分钟,直到我的应用程序超时,根据JFR记录在此期间读取0字节。在此期间我没有看到任何SQL异常。当我的应用程序超时并关闭连接时,我收到 java.io.IOException:Broken pipe 。
这只会偶尔发生,后续调用不会遇到此问题。我没有直接访问远程MySQL服务器或运行我的应用程序的网络。知道什么可能导致这种情况以及如何解决这个问题?