中年|架构师写的BUG,非比寻常


部门新来了个架构师 , BAT背景 , 住在三环 , 开宝马上班 , 有车位 。
小伙话不多 , 但一旦说话斩钉截铁 , 带着无法撼动的自信 。 原因就是 , 有他着数亿高并发经验 , 每一秒钟的请求 , 都是其他企业运行一年也无法企及的 。 这就让人非常羡慕 , 毕竟他靠这个比我赚的钱要多 。
俗话说 , 要想在公司不出事故 , 那就不要写代码 。 干活多了容易出事 , 一身轻松无人问津 , 这就是现实 。
但有时候还是要看成果的 。 新来的研发领导不懂技术 , 但他懂技术指标 , 所以就统计大家提交git的数量 , 如果git活动是一片绿色如A股 , 那就算过关了 。
架构师思来想去 , 决定领一个并发量最高的需求:统计接口的平均响应时间和启动以来的请求数 。
为什么说它的并发量高呢?这是因为 , 它是统计所有接口的 , 自然比每一个接口的请求量都要大 。 AOP代码一包 , 每个接口都得从他这里走一圈 。
该我们的架构师上场了 。 代码如图 。
【中年|架构师写的BUG,非比寻常】中年|架构师写的BUG,非比寻常
本文插图

架构师说 , 我的代码不需要做注释 。 所谓的注释 , 都是给垃圾代码用的 。 我深以为是 , 他明显是受到了Netflix公司的影响 。

程序考虑到了高并发场景 , 使用了线程安全的ConcurrentHashMap , 然后每次通过监控key取出相应的数据 , 然后在value上递增 。 这么简单的代码 , 确实不需要增加什么注释 。
作为项目里并发量最高的代码 , 出于对高级架构师的信任 , 我们并不需要做什么代码review , 也不需要做什么测试 。 大家都很忙 , 代码您呐 , 到线上遛一遛吧 。
我建议你先找一找代码的问题 , 如果你发现了问题 , 那就比架构师还厉害;如果你没发现 , 也不证明你比架构师弱 , 没有什么好伤心的 。
下面插一副图 , 阻断一下思维 。
中年|架构师写的BUG,非比寻常
本文插图

装B遭雷劈 , 线上运行一段时间后 , 内存溢出了 。
大家吵吵个没完 , 毕竟xjjdog说过 , 内存溢出问题的排查周期很长 , 大约平均需要40天左右才能解决问题 。 在大家开始论证的时候 , 架构师偷偷的启动了Eclipse MAT 。 MAT用来分析内存问题是非常合适的 , 但前提是你需要把堆栈给捣鼓下来 。
架构师会用jmap , 最主要的是权限大 , 于是自己搞了一份拷贝到线下分析 。
我能理解到他的心情 , 毕竟问题定位到自己的代码不是一件什么值得高兴的事情 。 他发现内存的堆里面 , 满满的全是MonitorKey和MonitorValue 。
Monitor$MonitorKey@15aeb7ab

我和架构师关系比较好 , 于是他问我:咱们的接口是不是特别的多?
我说:不是啊 , 你别看访问量大 , 就这么个狗屁业务能有多少接口?几百个撑了天了 。
他说:我在堆里发现了几千万个...
说完他就不言语了 , 因为他发现里面有不少是一样的接口 。 一定是参数的原因 , 所以他在代码里加了这个 , 把?后面的给截断了 。
key = key.split("\?")[0]
结果发布到线上 , 过不了多久内存又溢出了 。 这次终于引起了大牛们的注意 , 经过大家的分析 , 发现代码是忘了给MonitorKey重写equals和hashCode方法了 。
我不禁脸红起来 。 作为好朋友 , 我不应该让他出这个丑 。 但我又是隐隐快乐的 , 因为他工资比我高 。
所以这就是一个很大的问题 。 很多同学对HashMap的知识点对答如流 , 甚至还专门记忆了红黑树 。 但换一个方式去问 , 却又一脸懵逼 。
其中一种问法是这样的:一个普通的对象 , 能够作为HashMap的key么?


推荐阅读