Yhzhtk / note

知识代码笔记
https://github.com/Yhzhtk/note/issues
MIT License
108 stars 11 forks source link

Mysql链接超时,CPU一直占用 (socketAvailable) #20

Open Yhzhtk opened 9 years ago

Yhzhtk commented 9 years ago

问题发现

1、监控服务器,发现负载中平均升高了一个,而其中的System CPU使用率一直维持在60左右。 2、查看TOP -H 发现其中一个线程的的CPU使用率一直是100,恰好完整占用一核(系统是4核) 3、用jstack导出堆栈,找到CPU高的这个线程堆栈信息如下:

    java.lang.Thread.State: RUNNABLE
        at java.net.PlainSocketImpl.socketAvailable(Native Method)
        at java.net.AbstractPlainSocketImpl.available(AbstractPlainSocketImpl.java:478)
        - locked <0x00000006bae63f90> (a java.net.SocksSocketImpl)
        at java.net.SocketInputStream.available(SocketInputStream.java:245)
        at com.mysql.jdbc.util.ReadAheadInputStream.available(ReadAheadInputStream.java:232)
        at com.mysql.jdbc.MysqlIO.clearInputStream(MysqlIO.java:949)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2404)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2629)
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2719)
        - locked <0x00000006bae5c360> (a com.mysql.jdbc.JDBC4Connection)
        at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
        - locked <0x00000006bae5c360> (a com.mysql.jdbc.JDBC4Connection)
        at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2318)
        - locked <0x00000006bae5c360> (a com.mysql.jdbc.JDBC4Connection)
        at com.jolbox.bonecp.PreparedStatementHandle.executeQuery(PreparedStatementHandle.java:172)
        at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.selectSchedulerStateRecords(StdJDBCDelegate.java:2949)
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.findFailedInstances(JobStoreSupport.java:3294)
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.clusterCheckIn(JobStoreSupport.java:3380)
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.doCheckin(JobStoreSupport.java:3240)
        at org.quartz.impl.jdbcjobstore.JobStoreSupport$ClusterManager.manage(JobStoreSupport.java:3857)
        at org.quartz.impl.jdbcjobstore.JobStoreSupport$ClusterManager.run(JobStoreSupport.java:3894)

4、发现该线程一直停在 java.net.PlainSocketImpl.socketAvailable(Native Method),是一个Native方法。 5、在StackOverFlow上搜索该问题,链接,发现这是因为Mysql服务器已经把链接断开了,而本机仍在一直等待,未设定超时机制不停的等待。

解决办法:

在Mysql执行时设定超时,包括connectTimeOut和socketTimeOut。

jdbc:mysql://xxx:6446/xxx?autoReconnect=true&connectTimeout=60000&socketTimeout=60000