日常Bug排查-消息不消费
日常Bug排查-消息不消费
前言
日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材_。
Bug现场
某天下午,在笔者研究某个问题正high的时候。开发突然找到笔者,线上某个系统突然消费不了queue了。Queue不消费也算是日常问题了。淡定的先把流量切到另一个机房,让问题先恢复再说。
消息累积
然后就是看不消费的queue到哪去了,打开mq(消息中间件)控制台,全部累积到mq上了。

同时开发对笔者反映,只有这个queueu积累了,其它queue还是能正常消费的。
出问题时间点
这时笔者还得到了一个关键信息,此问题是DBA对其关联的数据库进行操作后才发生的。当时由于操作灌入的数据库过大,导致数据库主从切换,漂了VIP。从时间点判断,这个应该是问题的诱因。
jstack
既然卡住了,那么老办法,jstack一下,看看我们的mq消费线程在干嘛:
ActiveMQ Session Task-1234
at java.net.SocketInputStream.socketRead0
......
at com.mysql.jdbc.MysqlIO.readFully
......
at org.apache.activemq.ActiveMQMessageConsumer.dispatch
......
很明显的,都卡在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或者重启了。
总结
要保证高可用,任何远程调用都需要设置超时。否则就会导致应用长时间无法响应这样的现象。

日常Bug排查-消息不消费的更多相关文章
- 日常Bug排查-系统失去响应-Redis使用不当
日常Bug排查-系统失去响应-Redis使用不当 前言 日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材_. Bug现场 开发反应线上系统出现失去响 ...
- 日常Bug排查-抛异常不回滚
日常Bug排查-抛异常不回滚 前言 日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材_. Bug现场 最近有人反映java应用操作数据库的时候,抛异 ...
- 日常Bug排查-Nginx重复请求?
日常Bug排查-Nginx重复请求? 前言 日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,其中不乏一些看起来很低级但很容易犯的问题. 问题现场 有一天运维突然找到 ...
- Spring Cloud Stream如何处理消息重复消费?
最近收到好几个类似的问题:使用Spring Cloud Stream操作RabbitMQ或Kafka的时候,出现消息重复消费的问题.通过沟通与排查下来主要还是用户对消费组的认识不够.其实,在之前的博文 ...
- ActiveMQ消息的消费原理
消费端消费消息: 在 初识ActiveMQ 中我提到过,两种方法可以接收消息,一种是使用同步阻塞的ActiveMQMessageConsumer#receive方法.另一种是使用消息监听器Messag ...
- 记一次线上bug排查-quartz线程调度相关
记一次线上bug排查,与各位共同探讨. 概述:使用quartz做的定时任务,正式生产环境有个任务延迟了1小时之久才触发.在这一小时里各种排查找不出问题,直到延迟时间结束了,该任务才珊珊触发.原因主要就 ...
- 分布式消息服务DMS如何实现死信消息的消费
本文部分内容节选自华为云帮助中心的分布式消息服务(DMS)服务的产品介绍 死信消息是什么 死信消息是指无法被正常消费的消息.分布式消息服务DMS支持对消息进行异常处理.当消息进行多次重复消费仍然失败后 ...
- NSQ源码剖析——主要结构方法和消息生产消费过程
目录 1 概述 2 主要结构体及方法 2.1 NSQD 2.2 tcpServer 2.3 protocolV2 2.4 clientV2 2.5 Topic 2.6 channel 3 启动过程 4 ...
- springboot项目整合rabbitMq涉及消息的发送确认,消息的消费确认机制,延时队列的实现
1.引入maven依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactI ...
随机推荐
- HACK TEH BOX - Under Construction(JWT密钥混淆 + SQL注入)
HACK TEH BOX - Under Construction(JWT密钥混淆 + SQL注入) 目录 1. JWT密钥混淆 2. 环境 3. Challenge 4. Walkthrough 1 ...
- 各种平衡树收集(收集控(‐^▽^‐))\平衡树模板题的各种花式做法QAQ
非旋转treap!!!(FHQ Treap) 递归版Splay(无需维护父指针) Scapegoat _ Tree--替罪羊树(一只(棵)特立独行的猪(树)) 宗法树(平衡线段树\finger_tre ...
- 【Java】说说你对ThreadLocal的理解
思路: 0.ThreadLocal是什么?有什么用? 1.ThreadLocal用在什么地方? 2.ThreadLocal的一些细节 3.ThreadLocal的最佳实践 一.ThreadLocal用 ...
- 淘宝欺骗病毒的鉴定--TaBAccelerate.dll
样本名称:TaBAccelerate.dll 样本大小:1135104 字节 样本MD5:7AEF6EEECB37685D17F3D9BD76FA9EA0 样本SHA1: EB1E5ABA7C3797 ...
- POJ 2762 单连通图
题意: 给你一个有向图,问你这个图是不是单连通图,单连通就是任意两点之间至少存在一条可达路径. 思路: 先强连通所点,重新建图,此时的图不存在环,然后我们在看看是否存在一条路径可以 ...
- Python小程序 -- 人民币小写转大写辅助工具
大家应该都知道,银行打印账单有时候会跟上人民币的阿拉伯数字以及人民币汉字大写写法,转换的过程中有一定的逻辑难度,较为麻烦,所以笔者心血来潮,花了点时间简单实现了一下这一转换过程,以供初学者参考. 输入 ...
- hdu5033 最大仰望角
题意: 给你n个楼房排成一条直线,楼房可以看成是宽度为1的线段,然后给你m组询问,每组询问给你一个坐标,输出在当前坐标仰望天空的可视角度. 思路: n比较大,O(n*m)肯定跪 ...
- 缓冲区溢出之栈溢出利用(手动编写无 payload 的 Exploit)
0x01 介绍 Exploit 的英文意思就是利用,它在黑客眼里就是漏洞利用.有漏洞不一定就有Exploit(利用),有Exploit就肯定有漏洞.编写缓冲区溢出的Exploit分为3个方面:漏洞溢出 ...
- UVA10905孩子们的游戏
题意: 给你n个数字,让你用这n个数组组成一个最大的数字并输出来. 思路: 这个题目看完第一反应就是直接按照字符串排序,然后轻轻松松写完,交上去直接wa了,为什么会wa呢?感觉 ...
- MinGW 可以编译驱动的
#include <ddk/ntddk.h> static VOID STDCALLmy_unload( IN PDRIVER_OBJECT DriverObject ) {} NTSTA ...