惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
C
Check Point Blog
J
Java Code Geeks
腾讯CDC
Martin Fowler
Martin Fowler
MongoDB | Blog
MongoDB | Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - 三生石上(FineUI控件)
Apple Machine Learning Research
Apple Machine Learning Research
大猫的无限游戏
大猫的无限游戏
Engineering at Meta
Engineering at Meta
罗磊的独立博客
Last Week in AI
Last Week in AI
B
Blog
IT之家
IT之家
S
SegmentFault 最新的问题
D
DataBreaches.Net
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
GbyAI
GbyAI
博客园 - 聂微东
U
Unit 42
有赞技术团队
有赞技术团队
Y
Y Combinator Blog
MyScale Blog
MyScale Blog

博客园 - 寒魔影

Linux waitpid函数分析 不同进程内相同的变量内存地址是相同的 Linux 内存虚拟地址介绍 Sword B树学习笔记二 Sword B树学习笔记一 defined but not used警告屏蔽 apisix流量高峰期服务卡住问题 服务卡死现象分析实录 服务资源加载延迟异常增加 Linux 常用命令四 TCP全连接队列 调用writev收到信号SIGPIPE问题分析记录 epoll_wait监听事件延迟问题记录 writev发送数据失败 C++ new关键字运算符重载 Missing separate debuginfos类型崩溃分析 宏定义导致数据异常问题 C语言 数据类型 Linux 终端光标控制函数
服务压测偶现卡住问题分析
寒魔影 · 2023-12-28 · via 博客园 - 寒魔影

服务框架介绍

服务是一个生产者,一个消费者,通过对象池分配对象,通过加锁队列进行数据交互。

现象

通过观察服务日志,发现服务经常报timeout错误

初步定位

内核打印执行步骤,发现服务是阻塞在最后一帧,由于内核没有发出最后一帧,因此服务一直在尝试获取最后一帧

详细日志分析

通过分析,发现最后一帧数据没有发出来是因为队列中数据被破坏了,生产者生产了数据,压入队列,消费者在提取数据时,队列中链表关系就被破坏了

分析过程

第一步:因为对象池和加锁队列都已经运行5年了,开始不能怀疑是这两个结构出了问题,对于这种异常,先怀疑是最近修改的代码导致内存越界,因此引发这种异常现象。
结论:通过内存检测工具,未发现内核有内存泄露

第二步:开始分别阅读对象池和加锁队列源码
结论:两份源码都没有发现异常,但是发现对象池和加锁队列共用一个队列,两者都会对元素的前项指针和后项指针进行操作,这是有问题的

第三步:放弃使用对象池,直接分配内存
结论:问题被解决,但是实现方案不好,频繁分配内存会造成内存碎片,继续研究对象池方案

第四步:拆分对象池和加锁队列,让他们使用不同的链表节点
结论:测试下来没有解决问题

第五步:继续加日志,分析日志
结论:在分析过程中发现服务运行中会出现队列中的数据和队列长度不一致的情况。

第六步:对于数据和队列长度不一致的情况,怀疑是队列没有加锁导致,对队列加锁部分增加日志
结论:队列加锁没有问题,但是偶然发现从对象池中获取数据,在没有归还之前居然还可以取出来继续被使用,这里不符合预期,
检查对象池代码,发现对象池和加锁队列还是共用的一个链表节点,修改代码继续测试

最终结论:问题解决。

小结

其实对象池本身是没有问题的,加锁队列本身也是没有问题。当时在第二步我就发现对象池和加锁队列共用链表可能有问题,
但是当时修改代码不细致,得出了第四步错误的结论,使得我定位问题多花了一天时间。
定位这种问题,修改代码一定要细节,修改的部分可以加日志确认,问题分析正确由于错误的编码得出错误的结论是不应该的。