从一滴水开始 的个人博客

纵有疾风起,人生不言弃

Open Source, Open Mind,
Open Sight, Open Future!
  menu
20 文章
8821 浏览
1 当前访客
ღゝ◡╹)ノ❤️

Communications link failure during rollback(). Transaction resolution unknown

  • 错误描述如图:

image.png

  • 错误背景:

使用SpringBoot + Druid + myqsl开发应用服务,使用Nginx做4层代理转发到Mysql服务端。服务启动后再swagger上第一次访问接口是正常的,但是过了几十秒后再访问就报错了,后面就再也发不通了。一直提示无法建立连接

image.png

Communications link failure. The last packet successfully received from the server was 177,731 milliseconds ago. The last packet sent successfully to the server was 177,735 milliseconds ago.

  • 初步分析:

作为一名合格的程序员,必须有独立解决问题的能力(当然在我们部门,我也没有可以求救的人了),遇到不认识的异常就要会百度、Google~ 但是我左搜右搜上搜下搜,都找不到正确的解决方案。无奈,只能靠自己了。仔细看了下异常信息,是从com.alibaba.druid里抛出来的,难道是连接池的问题?于是我把Druid连接池换成了HikariCP,结果是可以正常访问数据库了,赶紧提交代码,别耽误其他同事的开发。

数据库不可访问的危机是解除了,但是日志里还是会打印一堆warn警告。如图:image.png

我是一个略有强迫症的程序员,解决问题必须要知其然且知其所以然,还有warn警告,说明问题并没有从根源上解决。于是我又仔细分析了下警告提示 从服务器成功接收到的最后一个数据包是177,731毫秒前。最后一个成功发送到服务器的数据包是177,735毫秒之前)。可以考虑使用更短的maxLifetime值,难道是配置有问题?我将 max-lifetime值调小,发现并没有任何作用。

“Communications link failure是通讯链路故障...接收数据包...发送数据包”,猜想问题可能出在通讯链路上。由于我的mysql是在内网服务器上的,没有直接将msyql服务器暴露到外网上,所以需要在nginx服务器做一个4层代理。我开始怀疑是不是nginx配置有问题呢,以下是我nginx的配置。image.png

proxy_connect_timeout是nginx连接上游服务超时时间,如果配置多个上游服务节点,且nginx路由到的第一个上游服务不可用时,连接超过设置的超时时间,nginx会自动将请求路由到其他上游服务节点。

proxy_timeout 是如果指定时间内,客户端没有请求发送过来,nginx会断开与上游节点的链接,以节省资源(查了以后才知道的)。

Mysql客户端与服务端之间是TCP长链接,在Mysql上是可以看到连接数的。于是我登录了mysql,进行了连接数的查询。show status like 'Threads%';

image.png

当我服务停止时,连接数为1,当我启动服务并进行一次接口调用后(会访问数据库),连接数变成了6。说明数据库根据我代码里配置的 minimum-idel为5初始化了5个连接。

image.png

10s后再次查看连接数变成了1,说明数据库认为客户端连接断开了,释放了5个连接。

image.png

再次访问接口变成了6,说明hikariCP默认实现了自动重连,数据库根据配置又重新创建了5个连接。

image.png

停止服务又变成了1,说明数据库识别到客户端断开后,释放了5个连接。

image.png

我们可以通过 show processlist;命令看一下数据库进程信息的状态。

最开始连接数为0,没有任何连接信息,只有执行 show processlist命令的查询进程。

image.png

服务启动后,数据库不会立即创建连接进程,调用一次查询后出现了5个进程,并且可以看到用户及其DB。Time为进程存在时间

image.png

image.png

可以看到Time增长到10s后,会自动消失。

image.png

总结

经过上面验证过程后,确定连接断开时间是与Nginx的proxy_timeout保持一致的,于是我把proxy_timeout配置取消后,观察连接是正常的,可持续到我们配置的interactive_timeout值。

(1)interactive_timeout:
参数含义:服务器关闭交互式连接前等待活动的秒数。交互式客户端定义为在mysql_real_connect()中使用CLIENT_INTERACTIVE选项的客户端。
参数默认值:28800秒(8小时)

(2)wait_timeout:
参数含义:服务器关闭非交互连接之前等待活动的秒数。
在线程启动时,根据全局wait_timeout值或全局interactive_timeout值初始化会话wait_timeout值,取决于客户端类型(由mysql_real_connect()的连接选项CLIENT_INTERACTIVE定义)。
参数默认值:28800秒(8小时)


标题:Communications link failure during rollback(). Transaction resolution unknown
作者:从一滴水开始
地址:http://blog.lizhenhua.fun/articles/2021/10/21/1634811865854.html