原创:小姐姐品味(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。有时,由于业务的复杂性,将一些数据组装到JVM中会造成资源的极大浪费。比如从MySQL中查询一个List,然后在代码中循环遍历数据库,填充一些字段。这种数据组装方式,除了执行效率的问题外,往往内存占用较多,对整个JVM计算节点造成比较大的压力,有时甚至会造成内存溢出。因此,一些比较厉害的开发人员使用非常复杂的SQL,将这些耗时的操作转移到数据库中。可怜的数据库成了最后一道屏障。谁让数据库的配置普遍较高?值得的。但遗憾的是,数据库也需要经过耗时的操作才能完成这些动作。如果Java线程不耐烦,它会直接返回一个超时给用户。在这种情况下,迷茫的用户会再次发起重试。要知道Java端超时并不代表发起的请求已经结束。在一些高并发场景下,性能差的数据库会跑一些耗时慢的查询,计算一些未知的数据。可怜的数据库。1、如何设置数据库超时时间对于mysql数据库,有两个可用参数:connectTimeout默认值:0,单位:毫秒配置连接超时时间,通过connect(SocketAddressendpoint,inttimeout)Socket对象的方法:0,单位:ms配置socket的超时时间,通过Socket对象的setSoTimeout(inttimeout)方法配置示例:jdbc:mysql://xxx.xx.xxx.xxx:3306/数据库?connectTimeout=60000&socketTimeout=600002。timeout的含义当数据库宕机或者网络异常时,需要jdbc驱动的socket超时。由于TPC/IP的结构,socket无法检测网络错误,因此应用程序无法检测到与数据库的连接是否已经断开。如果没有设置套接字超时,应用程序将等待数据库返回结果。为了避免死连接,套接字必须设置一个超时时间。通过设置超时时间,可以防止出现网络错误时等待的情况,缩短失败时间。一般的数据库连接池都会提供链接检查的功能,但是已经在使用的连接往往不会再检查。3、配置测试3.1、connectTimeout当设置connectTimeout=1时,建立数据库连接时出错。该值在建立数据库连接时有效。3.2.socketTimeout构造慢查询,设置socketTimeout小于慢查询时间,如:socketTimeout=1000&connectTimeout=1000,慢查询执行时间为100S。执行查询时,关键异常日志:...警告o.s.jdbc.support.SQLErrorCodesFactory218-提取数据库名称时出错-回退到空错误代码org.springframework.jdbc.support.MetaDataAccessException:提取DatabaseMetaData时出错;嵌套异常是com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:连接关闭后不允许进行任何操作。原因:com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:连接关闭后不允许进行任何操作。Causedby:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:Communicationslinkfailure从服务器成功接收到的最后一个数据包是在1,029毫秒前。最后一个成功发送到服务器的数据包是在1,006毫秒之前。Causedby:java.net.SocketTimeoutException:在java.net.SocketInputStream.socketRead(SocketInputStream.java:116)在java.net.SocketInputStream.socketRead0(NativeMethod)读取超时va.net.SocketInputStream.read(SocketInputStream.java:171)在java.net.SocketInputStream.read(SocketInputStream.java:141)在com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:101)在com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:144)在com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:174)在com.mysql.jdbc.MysqlIO.readIOFully(Mysql:3008))atcom.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3469)...省略了137个公共帧返回错误码,springSQLErrorCodesFactory异常转换失败2)连接建立后connectTimeout参数将不再生效3)SHOWPROCESSLIST查看mysql上正在执行的查询,发现慢查询还在执行,那就是说,对于慢查询,此时断开连接并不会终止慢查询的执行。这就像你找了一个女孩结婚,种下种子,最后因为错的家庭而分崩离析。但是这个案子的种子悄然结出果实。4.综上所述,socketTimeout参数有设置的意义。查询时间超过一定阈值后,断开连接可以防止客户端的连接一直被占用。另外,对于slowcheck监控,这种异常不直接统计运行时间(因为客户端连接断开,sql执行未完成),但可以根据异常类型单独判断,即有用的对于这种严重的慢速检查监控非常重要的实际意义。作者简介:品味小姐姐(xjjdog),一个不允许程序员走弯路的公众号。专注于基础架构和Linux。十年架构,每天百亿流量,与你探讨高并发世界,给你不一样的滋味。我的个人微信xjjdog0,欢迎加好友进一步交流。
