共计 1082 个字符,预计需要花费 3 分钟才能阅读完成。
通过一次略微大的改版后,零碎上线,上线后测试没发现问题,第二天反馈系统卡顿,下线。
查看零碎问题 , 优化接口速度 上线,上线后发现没问题,第二天仍旧呈现卡顿。此时察看 CPU 占用 1600%. 此时想到的时先回滚。没有保留现场。
测试环境测试,发现 cpu 闲暇时占用 100% 找到问题 修复。然而能够确定,这里 100% 不是引起 1600% 的起因。
再次上线,人工实时监控 cpu 占用率。此时呈现了 1600% 的状况。此时占用 cpu 1600% 的过程对应的线程如下.
6619 6625 等是占用最高的过程 Id.
对 JVM 栈信息进行打印 并输入到文件。
6619 转成 16 进制后为 19db 依据过程号在栈文件中
最初发现占用 cpu 高的全副为 gc 过程,此时能够断定。有局部代码逻辑内存占用过高。或者呈现内存透露。
寻找问题
此时曾经间断三次上线失败,没方法在从线上测试。那么想的是在灰度环境模拟这个景象 而后 dump 堆信息 这样必定能够找到起因。
第一天 转移很少一部其余零碎流量,以及很少一部分用户流量过来,没发现问题。
第二天 其余零碎申请的流量放弃不变,减少更多的用户流量,没有复现问题。
第三天 减少局部其余零碎申请的流量,没有复现问题。
第 n 天 减少其余零碎申请的流量 内存调整小,没有复现问题。
第 n + 1 天 灰度环境服务与正式环境平分流量,持续减少用户量。没呈现问题。
此时外围流程代码批改过的局部 曾经查看了 n 遍 没发现问题。
那么 须要思考一下,为什么灰度环境没有问题。而线上有问题。他们的用户有什么不同?
此时发现灰度环境全是权限最低的用户,而管理员没有在灰度环境上工作,想到这里 问题曾经离假相很近了。能够说曾经定位到问题所在了,只须要验证一下本人的猜测。
其中有个性能,是查看本人所治理人的数据,这个性能因为不是外围性能,并且申请的量很小很小,起初并没有向这个方向思考。
逻辑是:查找本人下一级别,如果有数据,在持续查找,恰好 数据库有一条异样的数据,他的下一级就是本人!导致产生了死循环,导致内存里的数据越来越多。
并且 只有那一个异样用户才会引起这个问题!
又因为是 IO 密集的操作,所以 这个循环占用的 cpu 很低。在线程栈中并没有发现他。
解决问题
找到问题解决就是很容易的事件了,不再详细描述。
反思
第一次零碎呈现卡顿,正确的解决形式大略应该如下
发现 cpu 占用高,查看该过程对应的线程在执行什么操作
发现大量的线程远程桌面在执行 gc 操作,此时应该 dump 堆信息
应用 jmap 等工具查看哪些对象占用内存占用高
找到对应代码 解决问题
这种 bug 不应该存在,即便存在了呈现问题也不要太慌 应该疾速的保留能保留下来的信息。
大的改变上线前须要灰度公布,大量用户先应用。
完结