由于业务应用 bug(本身或引入第三方库)、环境原因、硬件问题等原因,线上服务出现故障 / 问题几乎不可避免。例如,常见的现象包括请求超时、用户明显感受到系统发生卡顿等等。
作为一个合格的研发人员(技术人员),不仅要能写得一手好代码,掌握如何排查问题技巧也是研发人进阶必须掌握的实战技能。这里提到的排查问题不仅仅是在Coding的过程中Debug,还包括测试阶段、线上发布阶段问题的排查。特别是在生产环境中,一般是没办法或很难进行Debug操作的。 而通过掌握服务线上问题排查思路并能够熟练排查问题常用工具 / 命令 / 平台来获取运行时的具体情况,这些运行时信息包括但不限于运行日志、异常堆栈、堆使用情况、GC情况、JVM参数情况、线程情况等。
排查出问题并找到根本原因加以解决,其实是一件很成就感的事情。曾经有人问过我:“你是怎么想到问题出现在xxx的?又是怎么确认根本原因是xxx的?”,我只能轻描淡写的回答:“靠经验”,其实这里说的“靠经验”是很模糊的,一直以来大家可能都觉得排查问题要靠经验,但是又说不出具体通过什么样的经验排查出了问题。而本质上排查定位线上问题是具有一定技巧或者说是经验规律的,排查者如果对业务系统了解得越深入,那么相对来说定位也会容易一些。排查问题的关键是什么?一句话总结:给一个系统定位排查问题的时候,知识、经验是关键,数据是依据,工具是运用知识处理数据的手段!在此,我将结合自身经历、总结,说关于“问题排查”的方法论,希望能与您产生更多的共鸣。
注:由于针对不同技术问题,所用到的排查工具,命令千差万别,所以本文将只介绍思路,不涉及具体排查命令的介绍。
有哪些常见的问题
那我们经常说遇到这样那样的问题,那到底有哪些问题,问题又集中在哪些方面?对于不同技术框架、语言族所可能引发的问题也会存在很大的差异,但基本的套路排查思路都还是一致的,以Java为例。
所有 Java 服务的线上问题从系统表象来看归结起来总共有四方面:CPU、内存、磁盘、网络。例如 CPU 使用率峰值突然飚高、内存溢出 (泄露)、磁盘满了、网络流量异常、FullGC 等等问题。
基于这些现象我们可以将线上问题分成两大类: 系统异常、业务服务异常。
1. 系统异常
常见的系统异常现象包括: CPU 占用率过高、CPU 上下文切换频率次数较高、磁盘满了、磁盘 I/O 过于频繁、网络流量异常 (连接数过多)、系统可用内存长期处于较低值 (导致 oom killer) 等等。
这些问题如果是在Linux系统下可以通过 top(cpu)、free(内存)、df(磁盘)、dstat(网络流量)、pstack、vmstat、strace(底层系统调用) 等工具获取系统异常现象数据。
注:CPU 是系统重要的监控指标,能够分析系统的整体运行状况。对CPU的分析或监控指标,一般包括运行队列、CPU 使用率和上下文切换等,内存是排查线上问题的重要参考依据,内存问题很多时候是引起 CPU 使用率较高的主要因素。
而经常遇到内存占用飙高它的原因可能有很多。最常见的就是内存泄露。可以得到堆dump文件后,进行对象分析。如果有大量对象在持续被引用,并没有被释放掉,那就产生了内存泄露,就要结合代码,把不用的对象释放掉
2. 业务服务异常
常见的业务服务异常现象包括: