Java Communications link failure| Java Debug 笔记


theme: channing-cyan

本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看 活动链接

问题背景

运营人员在系统选择了一批数据,然后提交请求处理,一段时间后,运营找到开发说,我提交的数据一部分成功了,剩下的一部分还在处理中状态,一直没有更新。

定位分析思路

通过kibana日志追踪(代码中业务日志),如图,请求的确是已受理,并且依赖的微服务也返回了结果,但是最终修改数据库对应数据的状态却没执行!

image.png

起初以为是代码问题,但是再次code review并没有发现问题,而且运营也说了部分成功,让他们再次操作也都再次成功了。那么既然review代码没有发现问题,就再看看日志,是否有其他错误出现。

从代码发现log.info()日志后,下一步就是更新数据操作,所以便想到查看周围日志了解情况,点击这里,如图

image.png 发现一个附近有一个error log image.png

来分析一下这段话的意思: discard connection: 丢起连接 Communications link failure:通信链路故障 he last packet successfully received from the server was 1,927,021 milliseconds ago. The last packet sent successfully to the server was 0 milliseconds ago: 它最后一次成功收到来自服务器(mysql server)的数据包是在1,927,021毫秒之前。最后一个成功发送到服务器的报文是0毫秒之前

解决问题

错误的原因:MySQL服务在长时间不连接之后断开了,断开之后的首次请求会抛出这个异常

  1. 检查你的数据库连接地址(配置文件中的url)是否正确.
  2. 重启应用程序。(不建议,治标不治本)
  3. mysql5以前的版本可以直接在jdbc连接url的配置中附加上autoReconnect=true
  4. 查看和连接mysql时间有关的系统变量:show variables like '%timeout%' image.png > * interactivetimeout:默认值:28800秒(8小时) 服务器关闭交互式连接前,等待活动的秒数。(交互式客户端定义为在mysqlrealconnect()中使用CLIENTINTERACTIVE选项的客户端) > * waittimeout:默认值:28800秒(8小时) 服务器关闭非交互连接之前,等待活动的秒数。在线程启动时,根据全局wait_timeout值或全局interactive_timeout值初始化会话wait_timeout值,取决于客户端类型(由mysqlrealconnect()的连接选项CLIENTINTERACTIVE定义)。

如果在wait_timeout秒期间内,数据库连接(java.sql.Connection)一直处于等待状态,mysql5就将该连接关闭。这时,你的Java应用的连接池仍然合法地持有该连接的引用。当用该连接来进行数据库操作时,就碰到上述错误。

  1. 将mysql的全局变量wait_timeout的值修改为最大。查看mysql5的手册,发现windows和linux下wait_timeout的最大值分别是24天和365天

    1. 在文件my.ini的最后增加一行:wait_timeout=1814400。(该文件,windows下在mysql的安装目录下,linux下位置为/etc/my.ini)
    2. 重启mysql。
  2. 如果经过了以上的步骤,你的问题依旧没有的到解决,则建议你修改下你程序中的mysql驱动的版本。

扩展知识

mysql JDBC URL格式

jdbc:mysql://[host:port],[host:port].../[database][?参数名1][=参数值1][&参数名2][=参数值2]... image.png 在使用数据库连接池的情况下,最好设置如下两个参数 autoReconnect=true&failOverReadOnly=false

mysql与jdbc的操作文档

mysql5.1 jdbc 官方文档

mysql8.0 jdbc 官方文档

连接泄漏问题

从连接池中获取连接使用后忘记了连接的关闭,这样连池的连接就会逐渐达到maxActive直至连接池无法提供服务。可以使用如下方式避免该问题发生: ```

对于建立连接过长的连接强制关闭

druid.removeAbandoned:true

如果连接建立时间超过了30分钟,则强制将其关闭

druid.removeAbandonedTimeout:1800

将当前关闭动作记录到日志

druid.logAbandoned:true ```

removeAbandoned是连接池的高级功能,理论上这中配置不应该出现在实际的生产环境,因为有时应用程序执行长事务,可能这种情况下,会被连接池误回收,该种配置一般在程序测试阶段,为了定位连接泄漏的具体代码位置,被开启。生产环境中连接的关闭应该靠程序自己保证

关注+点赞👍收藏❤️不迷路

``` 文章每周持续更新,可以微信搜索「 十分钟学编程 」第一时间阅读和催更,如果这个文章写得还不错,觉得有点东西的话

各位的支持和认可,就是我创作的最大动力,我们下篇文章见!

```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蒋老湿

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值