问题
系统中功能批量插入,当数据量大了之后这个插入不进去了,报出异常如下
<span style="color:#000000">Caused <span style="color:#954121">by</span>: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:
Communications <span style="color:#954121">link</span> failurejdbc.exceptions.jdbc4.CommunicationsException:
Communications <span style="color:#954121">link</span> failure
The <span style="color:#954121"><span style="color:#954121">last</span></span> packet successfully received <span style="color:#0086b3">from</span> the server was <span style="color:#40a070"><span style="color:#40a070">179</span></span> <span style="color:#0086b3">milliseconds</span>
ago.
The <span style="color:#954121"><span style="color:#954121">last</span></span> packet sent successfully <span style="color:#0086b3">to</span> the server was <span style="color:#40a070"><span style="color:#40a070">180</span></span> <span style="color:#0086b3">milliseconds</span> ago.</span>
解决过程
其实这个问题特别简单,就是超时了,根据打印的sql记录,还能显示出执行插入sql的时候超时了。问题一目了然,对于这个模块来说本质上是循环插入的,但是这样数据库的IO操作比较多,所以我就把这一部分整合到一起插入,结果数据量大,插入方法时间执行过长了。
最简单的方式
将数据拆分每500条执行一次插入操作,缺点IO操作比较多,没有从本质解决问题。
彻底排除错误
排查过程
先说系统数据库连接这一部分配置
1、数据库
2、mycat
3、druid
4、p6sy
超时的问题就是上述某一部分或者某几部分连接超时造成,那就逐步排查吧。
1、p6sy
先排除p6sy,因为p6sy是将程序中执行的sql规范化,只是对执行sql加工处理,不涉及时间的问题。
2、Druid数据源
DruidDataSource配置属性列表
https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%88%97%E8%A1%A8
其中属性:timeBetweenEvictionRunsMillis,作用是: Destroy线程会检测连接的间隔时间,如果连接空闲时间大于等于minEvictableIdleTimeMillis则关闭物理连接。系统配置的是28800秒,将其调大后,问题没有解决,说明不是druid的配置造成的。
3、Mycat
这一部分的检测是直接将mycat换成直连mysql,根据判断问题是否解决,以验证是否为mycat造成的。
重试,问题依旧没有得到解决。
4、MySQL
经过上面的排查,可以得知MySQL的配置限制了程序的运行。查看MySQL的连接时间配置。
<span style="color:#000000"><span style="color:#954121"><span style="color:#954121">show</span></span> <span style="color:#954121"><span style="color:#954121">global</span></span> <span style="color:#954121">variables</span> <span style="color:#954121"><span style="color:#954121">like</span></span> “%timeout%”;</span>
简单介绍一下每个时间代表的意义
connect_timeout 连接超时 mysql连接共有6次握手,3次TCP协议这个跟connect_timeout参数没有关系,另外3次跟connect_timeout参数有关系,该参数主要是为了防止网络不佳时应用重连导致连接数涨太快,一般默认即可。
delayed_insert_timeout 这是为MyISAM INSERT DELAY设计的超时参数,在INSERT DELAY中止前等待INSERT语句的时间
interactive_timeout 服务器关闭交互式连接前等待活动的秒数。交互式客户端定义为在mysql_real_connect()中使用CLIENT_INTERACTIVE选项的客户端。参数默认值:28800秒(8小时)
lock_wait_timeout 锁等待超时时间
net_read_timeout / net_write_timeout 这个参数只对TCP/IP链接有效,分别是数据库等待接收客户端发送网络包和发送网络包给客户端的超时时间,这是在Activity状态下的线程才有效的参数
slave_net_timeout 解释:这是Slave判断主机是否挂掉的超时设置,在设定时间内依然没有获取到Master的回应就人为Master挂掉了
wait_timeout 服务器关闭非交互连接之前等待活动的秒数
分析上面超时时间代表的含义,再根据自己的情况,修改
解决方案
net_read_timeout/net_write_timeout的时间调大,重新测试完美解决!