办公常用软件技术学习网

办公常用软件技术学习网、Excel技术学习、PPT技术学习、Word技术学习、AI技术学习、PS技术学习,开发技术,数据库开发,SEO教程

联系客服联系客服

您现在的位置是:首页>技术开发>日常Bug排查-消息不消费

日常Bug排查-消息不消费

2021-06-04 11:33 栏目:技术开发

前言

日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材^_^。

Bug现场

某天下午,在笔者研究某个问题正high的时候。开发突然找到笔者,线上某个系统突然消费不了queue了。Queue不消费也算是日常问题了。淡定的先把流量切到另一个机房,让问题先恢复再说。

消息累积

然后就是看不消费的queue到哪去了,打开mq(消息中间件)控制台,全部累积到mq上了。

同时开发对笔者反映,只有这个queueu积累了,其它queue还是能正常消费的。

出问题时间点

这时笔者还得到了一个关键信息,此问题是DBA对其关联的数据库进行操作后才发生的。当时由于操作灌入的数据库过大,导致数据库主从切换,漂了VIP。从时间点判断,这个应该是问题的诱因。

jstack

既然卡住了,那么老办法,jstack一下,看看我们的mq消费线程在干嘛:

  1. ActiveMQ Session Task-1234 
  2.     at java.net.SocketInputStream.socketRead0 
  3.     ...... 
  4.     at com.mysql.jdbc.MysqlIO.readFully 
  5.     ...... 
  6.     at org.apache.activemq.ActiveMQMessageConsumer.dispatch 
  7.     ...... 

很明显的,都卡在MysqlIO.readFully也就是数据库读取上,再也不往下走了。

没配超时

这就肯定是没配超时了,排查了下他们的配置,确实没配。之前系统梳理过好多次,但没想到还是有这种漏网之鱼。这个问题分析本身是很简单的。不过在这里笔者想多聊一下,为什么数据主从切换会形成这样的现象。

mha切换

如图所示,mha切换逻辑是将vip从DB旧主上摘掉,然后将vip挂到DB新主上面。为了观察这种行为,笔者写了个python程序进行测试。观察得知,在vip被摘掉的那一刻,双方的通信已经不正常了。但是tcp连接状态依旧是ESTABLISHED。

为什么tcp状态依旧ESTABLISHED

因为ip摘掉并不会让已经存在的socket立马感知,那么socket什么时候能够感知到我们这个连接已经gg了呢。在当前这个场景下,应用没设置socket超时,会有这几种可能:

如果这时候App正在发请求给此五元组

如果DB正在写回请求给此五元组

由上面两种情况,我们可以知道哪方作出发送动作,哪方就能够通过reset或者尝试次数过多来感知到这个连接已经gg了。

很明显的,由于我们的应用正卡在socket read,表明我们的App应用并没有发送数据,而是在等待MySQL的返回,那么在不设置超时的情况下,App怎么感知到连接实际上已经不好了呢。

tcp保活定时器

由于应用不做发送动作,那这时就轮到我们的tcp保活定时器tcp_keepalive出马了。linux下默认的内核参数为:

/proc/sys/net/ipv4/tcp_keepalive_time 7200 两小时

/proc/sys/net/ipv4/tcp_keepalive_probes 9 探测9次

/proc/sys/net/ipv4/tcp_keepalive_intvl 75s 每次探测间隔75s

tcp保活定时器默认在7200s也就是两小时后开启,探测9次,每次间隔75s,如果有明确失败或者9次都没返回则判定连接gg。

在我们的这个场景中,应用会在两个小时后开始保活,在第一次探测的时候对端发送reset从而应用感知到连接gg。这时候,应用才返回。也就是说,不设置超时时间,遇到这种情况,应用的线程要卡2小时!

如果是DB进程宕or重启

如果不是mha切换,而是DB进程重启或者宕的话,由于Linux内核没宕还存在着。内核会自动将DB进程所属的socket进行close也就是发FIN报文回去。那么应用就可以立马从socket read系统调用中返回了。

物理机宕机

物理机宕机而不漂VIP,应用在不设置超时的时候。如果是发送数据阶段,则tcp_reties2次重试后从socket read系统调用返回。如果不发送数据,和上面的描述基本一样,2个小时后开启保活定时器。唯一不同的是,这次是需要探活9次,所以需要会多花11分钟左右的时间感知。

线下演练为什么不出问题

VIP漂移这种操作,我们在线下演练过,当时应用很快就切换完了。为什么到了线上就会卡住呢?这是因为,线下没有加上IO hang住导致SQL处理时间过长这一条件。SQL很快就返回了,所以我们线下的线程只有很小的概率卡在socket read上面。况且有几十个线程在消费,卡一两个无关大局。

而在我们这次上面,由于SQL处理时间超长,所以基本所有的线程都在VIP漂移的那一刻执行socket read即等待数据库返回阶段,就导致所有线程全部hang住等。这时候只能等待tcp_keepalive或者重启了。

【编辑推荐】

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区
  2. 以Rabbit MQ为例讲透消息队列
  3. 消息队列解耦是骗小孩儿的
  4. 【实战】Python与消息中间件
  5. 消息称微软6月24日发布全新Windows:十年来最重大变革
  6. 6月24日见!消息称微软将把下一代Windows命名为Windows 11!

上一篇:再见 FTP/SFTP,是时候拥抱下一代文件传输利器 Croc 了!

下一篇:使用Python自动化Microsoft Excel和Word