记一次线上 bug 的排查分析过程及总结

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 记一次线上 bug 的排查分析过程及总结

前言

大家好,我是路由器没有路

在线上运行的系统中,问题的出现是不可避免的。如何快速、准确地排查问题,是每个技术人员都需要掌握的技能。

本文将分享一个线上问题排查的过程和总结,希望对大家有所帮助。

问题表现

我们的商城系统有一个问题:有用户反馈打开商城首页有偶现打不开的情况。

前端查了下反馈说接口超时导致,但是查 cgi 接口进程还在,也无相关报错日志。

假设导致问题的原因

我们首先对问题进行假设,以便更好地进行排查。我们认为问题可能是由以下几种情况导致的:

  1. 网络异常导致
  2. 底层服务异常导致
  3. 底层服务慢查询导致
  4. 服务查询数据量大,回包给 cgi 有问题导致
  5. 接口有 panic 然后重启导致

小心验证

接下来,我们需要对每一种假设进行验证,以排除不符合实际的情况。

  1. 在网络正常的情况下,自己进商城首页试了下,确实也偶现该问题;接着让运维查了下网络带宽,也是正常的;排除网络异常导致。
  2. 查了下底层服务日志,日志无异常报错,进程也无重启情况,排除服务异常导致。
  3. 运维有工具监控慢查询的情况,有慢查询的话会有统计和告警的,查了下慢查询日志没有对应的慢查询;排除慢查询导致。
  4. 查了下该服务对应的 pl 日志,即框架平台日志(平台会有记录每次请求的包大小情况),看请求的包大小在正常阈值范围内,也无报包太大的错误,排除回包太大导致。
  5. 在日志系统查了下该接口的日志,并没有发现有 panic 或者其它异常的报错信息;此时一筹莫展,想着再看下部署机器上的接口进程是否都正常,仔细看发现有个别机器上的接口服务进程有重启过的情况,问了下同事也没有重启和发布的情况;猜测是代码有 bug 导致,于是再仔细 review 下代码的实现,果真是代码有 bug 导致的。

Bug 分析

通过排查,我们发现问题是由代码 bug 导致的

具体来说,平台框架代码有这么个实现:请求进来时 main goroutine 有一个 defer recover panic 的实现,如下所示:

main.png

正常如果接口有 panic 的情况会被框架 recover 掉,然后打印相应的错误日志,即在日志系统可以查到对应的报错信息。

但是在排查问题时,之所以没有查到有对应 panic 的日志的原因是:在 cgi 接口业务代码的一个方法中起了多个 goroutine,即开了并发处理一些业务数据汇总的逻辑,而这些新开的 goroutine 中并没有做 defer recover,也就是说当这些 goroutine 中发生异常 panic 的话,整个接口就会崩溃退出。

而这里的 bug 恰恰就是开多个 goroutine 并发写一个共享对象 map(mapFloorId2Idx) 产生竞争导致的(会报 fatal error: concurrent map writes 的异常信息),然后这里程序会重启的原因是有后台监控进程监控到并拉起。实现代码如下:

entry.png

大家可以想下为什么框架外层的 main goroutine 捕获不到其它 goroutine 的 panic?

原因很简单,就是 Golang 中的 goroutine 没办法跨协程 recover,从而导致程序崩掉

Golang 在发生 panic 时,是先找到本 goroutine,再在这个 goroutine 里的 defer 函数里看看有没有 recover

解决方案

通过分析,我们找到了问题的根本原因:开多个 goroutine 并发写一个共享对象 map 产生竞争导致的。为了解决这个问题,我们需要做两个方面的工作:

  1. 在多 goroutine 操作共享的对象 map 时上锁
  2. 内部的 goroutine 函数要 defer recover

总结

在排查线上问题时,我们需要做到以下几点:

  • 快速响应:一旦发现问题,需要立即响应,不能拖延;
  • 有条理地排查:需要有一定的排查思路和方法,按照假设进行验证,逐步排除不符合实际的情况;
  • 细心仔细:需要仔细查看日志、代码等信息,不能遗漏任何细节;
  • 总结归纳:需要将排查过程和结果进行总结归纳,以便在以后的工作中能够更好地应对类似问题。

通过本次排查,我们不仅解决了一个具体的问题,更重要的是积累了一定的排查经验和技巧,这对我们今后的工作将会有很大的帮助。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
6月前
|
测试技术
线上问题,如何处理?
线上问题,如何处理?
166 37
|
3月前
|
消息中间件 Java 调度
一次线上服务CPU100%的排查过程
文章记录了一次线上服务CPU使用率达到100%的排查过程,通过使用top命令和jstack工具确定了导致高CPU使用的线程,并分析了Disruptor组件的不当配置是问题原因,通过修改组件的策略成功解决了问题。
70 0
|
SQL 前端开发 测试技术
一次纯线上接口异常的排查过程
一次纯线上接口异常的排查过程
141 0
|
6月前
|
SQL 运维 监控
如何排查线上问题的?
在当今的互联网时代,线上问题对企业的业务连续性和用户体验产生的影响越来越大。无论是网站崩溃、应用性能下降,还是服务中断,这些问题都可能对企业的声誉和用户满意度造成严重影响。因此,快速、准确地排查并解决线上问题变得至关重要。本文将介绍一些高效的线上问题排查方法,帮助您在面对线上问题时,迅速定位并解决问题。我们将在接下来的内容中详细讨论如何利用日志分析、监控系统、代码审查等手段,以及如何制定有效的应急预案。通过这些策略的实施,您将能够提高线上问题的解决速度,减少对业务的影响,并提高用户满意度。
152 2
|
Java
【线上问题排查】内存泄漏排查(模拟真实环境)
【线上问题排查】内存泄漏排查(模拟真实环境)
196 0
|
消息中间件 运维 监控
线上踩坑记:项目中一次OOM的分析定位排查过程!
线上踩坑记:项目中一次OOM的分析定位排查过程!
|
运维 JavaScript 前端开发
记录两次多端排查问题的过程
记录两次多端排查问题的过程
|
Arthas NoSQL Java
线上服务器CPU100%的真相排查【Bug利器Arthas】
这起CPU100%的事故,由某个客户演示的bug暴露出来,气氛比较尴尬....
750 0
线上服务器CPU100%的真相排查【Bug利器Arthas】
|
SQL BI 数据库
记一次bug分析定位过程
其实很多时候,我们在测试过程中发现的很多bug,并不是由于开发人员编码能力不好,或者粗心大意造成,而是在项目开发实施过程中,没有遵循一些必要的项目流程,没有充分认识到质量的重要性;如果能做好这方面的工作,关注流程,而不是喊口号,人人重视质量,人人为结果负责,那么,会有很多问题、不只是bug,都将“被扼杀在摇篮里”......
记一次bug分析定位过程
|
SQL Java 数据库连接
线上运行的项目突然变得很卡如何排查?
线上运行的项目突然变得很卡如何排查?