数据库连接池阻塞的十五分钟

2020-05-17  本文已影响0人  费城的二鹏

业务反馈系统偶发卡顿,经过筛查复现卡顿时间的日志发现了日志内容如下:

居然有928秒的接口,发现的时候简直不敢相信自己的眼睛。首先怀疑接口存在性能问题,或者存在高并发的调用导致服务响应变慢,但是这个928秒也还是有些夸张。

结果翻查代码发现只有一个非常简单的sql查询,并且数据库的慢查询日志没有慢查询。翻查日志上下文发现,并没有高并发访问。并在尝试压测此接口时,发现远远达不到 928s 响应的情况,所以至此可以确定,是其它环境问题。

在上网寻找解决方案时,发现相关内容:

连接池 执行SQL超时15分钟
https://blog.csdn.net/u014155356/article/details/82865451

我们的网络通信过程如下:

Java服务器 <-> 防火墙 <-> 数据库服务器

防火墙会定时与不定时的删除 TCP 会话,在会话删除后,Java服务器使用连接池的连接发送数据库查询请求,过程如下:

  1. Java服务器建立连接池,经由防火墙与数据库建立三次握手的请求
  2. 此时防火墙认可这些连接,会正常转发这些请求
  3. 某时刻,防火墙删除此连接,不会发送 ASK 与 FIN 包
  4. Java服务器使用此连接发送数据库请求
  5. 防火墙收到请求后发现此连接无效,丢弃网络包,并且不会发送 ASK 包
  6. Java服务器在2*RTT后判定网络包丢失,因为没收到 SDK,所以默认判定网络发生拥塞
  7. 在系统设定的退避时到达后,再次发送重试包,如此循环,退避时间会随着重试次数的增加而增加
  8. 当重试次数到达系统设定上限后,(Linux 默认次数为15次),重新发起三次握手连接。

我截取的网络日志验证了上述描述内容。

本地测试重试时间为18s,服务器为928s,此时间与系统设定有关

上网查找了重试次数与所需时间的关系表。

为了解决此问题,上网查找了 Linux 可以修改,/proc/sys/net/ipv4/tcp_retries2 参数来减少重试次数,当网络环境较好时,可以减少到 5~6 次。

以上就是这十五分钟数据库做的事情,正常来说服务器会定时访问数据库来保持连接的存活性,可能防火墙存在问题,导致连接误杀,只有等网络部门解决后才能从根本上解决此问题。

by 费城的二鹏 2020.05.14 长春

上一篇下一篇

猜你喜欢

热点阅读