Communications link failure during rollback(). Transaction resolution unknown

从一滴水开始 的个人博客 纵有疾风起,人生不言弃 本文由博客端 http://www.lizhenhua.fun 主动推送

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 小时)

  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    609 引用 • 527 回帖 • 485 关注
  • Linux

    Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 Unix 的多用户、多任务、支持多线程和多 CPU 的操作系统。它能运行主要的 Unix 工具软件、应用程序和网络协议,并支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

    842 引用 • 907 回帖 • 235 关注
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    2990 引用 • 8141 回帖 • 593 关注

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...