工作中,你都遇到过哪些“高级”bug

Posted NetWhite

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了工作中,你都遇到过哪些“高级”bug相关的知识,希望对你有一定的参考价值。

前言

前两天在群里看到同学们在聊工作是消灭bug,后来谈到了“高级的bug”。

其实,我也没遇见过太高级的bug,可能是因为本身的工作就是普通开发的原因,平常遇到的bug也不是太高深。没有像传说中的那些硬件故障,“半夜拔掉空调插头手机充电导致主机过热引发bug”等那些神秘事件。

但是工作这几年也遇到过不少棘手的问题,查找bug花了不少时间,下面聊一下我自己工作中遇到过的那些棘手的bug。

棘手,肯定是当时网上搜不出来答案那种,要不怎么棘手呢。

其实有时候bug比较难查,也不定全都是代码太过复杂的原因,可能其中涉及的资源协调,领域不同都会导致排查处理起来比较麻烦或困难。

我遇到过的一些“高级bug”

因为工作中奇奇怪怪的bug也经常遇见,见的多了,能记住的就少了,就随便列出几个好描述的。

连接池神秘关闭事件

刚毕业那会参与了架构组自研的服务治理平台,负责了服务调用组件的研发。服务调用采用的是jersey的rest客户端,默认是HttpUrlConnector,底层是基于java的HttpUrlConnection,性能一般,也不支持连接池。我当时就引入了HttpClient的管理器,想要使用其连接池。但是我开发完成,进行测试的时候,每当启动后发起几次调用后,就会出现连接池异常关闭。后来我发现是一设置超时就出现这个问题,当时咨询组内一位大佬的时候,建议我抓包查下网络先。我没找到原因,也明白不是网络原因,当时能力有限,也没时间再查,就把这个功能先搁置下来,直到查下面这个bug的时候才找到根本原因。

性能优化,性能上来了,进程反而hang死?

在我说的上面那个问题,大概一年后,用的服务越来越多,场景复杂,性能问题也越发明显。终于在某个项目中和我们组当时开发的日志组件在非常底层的地方(jar包扫描),彻底引暴出了线上故障。我只能去优化了(当时日志的兄弟也是,各自优化各自的)。

优化的部分方案可以看这里:一些使用jersey的客户端API封装rest客户端优化建议

主要是减少类路径扫描及避免大对象的构造(dupm堆内存分析确认大对象)。

后来压测,压测同事反馈tps上来了,但运行10多分钟后进行hang死,主机CPU几乎100%。。。

性能上不来的时候,进程还能运行,性能上来,进程就hang死???

分析过程就不多说了,利用多种工具分析堆内存对象及线程栈和gc情况,综合起来才找到原因,当时有个记录:记一次full gc耗时且频繁的故障定位

是jersey的内部配置类,有个懒初始化维护状态的属性,并且实现了finalize方法,内部有一些关闭操作,它的这个配置为了保证上下继承的隔离还有个深copy的操作,总之,设计思想是好的,但是频繁构造就出问题了,性能上来出现了一个恶循环问题。

重写finalize方法的后果我的分析文章里有说明,最终导致频繁full gc了。同时也在这里有一些关闭操作,属性继承的原因,在GC的时候把上面的连接池也关闭了(就一个连接池神秘关闭那个问题),找到根本原因,就彻底解决了它,性能和稳定性在开启连接池后,都提升了好几倍。同时我又提供了一个更轻量级的调用组件来替换它,通过压测合理设置属性,性能比最初提升了10多倍。

zookeeper监听丢失

18年负责开发一个分布式配置平台,用了zk承载配置及监听。鉴于某些客户及场景方面特别需要,在设计数据结构的zk的节点层次并不规范,比如正常可能是这样:

--系统

------应用

--------环境/分组

--------------版本

---------------配置数据(下面可能还有实例什么的其它信息)

zk的深度正常应该像上面那样有层次感,但是有些其它原因(一些国际化的配置承载及固定场景),导致这个节点深度不固定,有的深有的浅,导致我编码的时候在客户端没法做很好的监听,我就想到一种特别的设计,这个纯粹我的原因,而后导致没有办法避免掉zk并发写监听丢失的问题:频繁操作zookeeper节点,客户端收不到监听通知

数据包断了

调用方是java写的,提供方是python+flask,中间用的nginx和某个插件转发,插件不支持http协议的chunk分块传输,导致请求一直有未正常结尾问题,我当时是好一顿抓包去查,而当时提供方还一直认为他们和nginx配置都没问题,非常不乐意配合,是真的麻烦。。。

代码正常未连接,显示已连接

服务调用显示已连接异常,查看源码确认还没走到建立连接的代码,这种问题简直就是觉得不可思议,后来猜测网络原因,协调网络组,结果是虚拟机调用容器,DNS解析有问题,what???

zookeeper主从数据同步问题

哎,这件事发生的时候我当时正在离职呢,结果有天晚上运维迁移zk数据也没打个招呼,让我看下他们流程正常不。次日早上出问题6点多把我叫公司,花了一个多小时查看zk日志,才找到原因,zk主从间数据同步有问题,其中一个节点重启选举时数据没同步过去,整个都是空的。当时可是导致某运营商某个省的客服电话没接法接入(随机的,因为只有一个zk节点有问题么),运维当时查的时候,还只看到了其它正常的节点,也没找到这个节点上,尴尬。。。

这个bug我后来花了一天去看源码验证,跟它的zab协议实现有点关系,有兴趣可以验证下,同时启动3个zk看下(要同时,其中要做主节点的有数据,另外两个从的没数据,等同步)。

RocketMQ的数据问题

印象深刻,也是半夜3点被叫起去公司查问题,大半夜查rocketmq的源码和一堆运维找原因。

其实rokcketmq的bug在最近半年,确实发现好几个也都提了issue,有时间顺便提了pr,不过大部分pr没被接受,尴尬。有几个bug我当时查的时候也是老费劲了,贴两个瞅瞅,一个broker的,一个go client的,其它的就不说了,太占篇幅了:

聊bug就到这里了。实际工作中遇到的奇怪bug太多了,也不想花太多时间,在这方面写的太多。

令我印象深刻的解决方案

bug不说了,分享个之前同事的2个解决方案,让我异常感叹,操作太秀了。

服务器不支持ruby环境

当时是有个系统要搭建redis,不支持ruby环境。组内一个大佬,半夜起来写了个c语言的环境解决了。反正我是对redis不熟悉,搁我可不行。

不知道这算不算“高级bug”。

应用内存泄露

当时是某个项目的文件句柄还是IO流啥的未关闭,他查问题的时候,修改jvm源码内存分配的地方,加个钩子,重新编译给这个项目运行。我听了只能直呼:666,搁我也就只能dump堆,mat走起来分析了。

最后

其实工作遇到的各种奇怪bug太多了,用的开源组件也可能有不少。我感觉这种代码层面的bug都不算太高级,毕竟程序员都会不小心写出一些bug的。

不知道同学们有没有遇到一些很难解的bug,欢迎评论分享。

以上是关于工作中,你都遇到过哪些“高级”bug的主要内容,如果未能解决你的问题,请参考以下文章

Spring 事务失效的 8 大场景,看看你都遇到过几个?

带你快速看完9.8分神作《Effective Java》—— 并发篇(工作里的这些坑你都遇到过吗?)

这些解决 Bug 的套路,你都会了不?

这些解决 Bug 的套路,你都会了不?

2021年,12个顶级开发工具,你都用过哪些?

2021 年,12 个顶级开发工具,你都用过哪些?