应对措施

定位

解决

复盘

海恩法则:每一起严重事故的背后,必然有29次轻微事故和300起未遂先兆以及1000起事故隐患

墨菲定律:如果有两种或者两种以上方式去做事,选择一种方式导致灾难,则必然会有人选择这种方式。

常见案例

CPU

原因
导致cpu过高一般有大量循环(甚至是死循环)、序列化反序列化慢、复杂的正则表达式、复杂打加密解密过程、大量反射、频繁的GC导致系统压力大、非常高频的日志输出导致系统压力过大、系统的锁竞争非常激烈导致大量的锁等待…

排查
当遇到cpu高的时候并不能单纯的认为就是上面的问题导致的,而要通过IO、系统压力、内存等多方面共同分析。
这里只是简单的分析单纯的CPU高的情况,特别是cpu us高

  • top 命令找到 CPU 消耗最高的进程
  • top -Hp [进程 ID] 找到 CPU 消耗最高的线程 ID
  • jstack 工具 dump 线程堆栈(jstack -l [进程 ID] >jstack.log)。
  • 线程 ID 是十进制的,堆栈信息中的线程 ID 是 16 进制的,将16 进制的,并用这个线程 ID 在堆栈中查找。使用
  • printf “%x\n” [十进制数字] ,可以将 10 进制转换成 16 进制。
  • 通过刚转换的 16 进制数字从堆栈信息里找到对应的线程堆栈。就可以从该堆栈中看出端倪。
  • 多dump几次,然后观察分析是那部分业务代码导致的。

**
我自己遇到过的有:锁竞争比较激烈、序列化缓慢、gc导致的,前两种用上面的方式可以快速的排查出来,特别注意其中wating和blocked线程即可。
入口区等待获取锁的线程状态为Blocked,获取锁失败,然后线程就排队等待。等待区等待被唤醒的线程状态为Waiting(Time_Waiting),线程在获取锁后调用自身的wait()方法,然后释放锁,进入等待区等待。
而gc导致的还需要结合heap dump来分析,很少会出现直接是gc线程导致的锁竞争问题。

cpu不高但是负载高
这种情况出现的根本原因在于不可中断睡眠态(TASK_UNINTERRUPTIBLE)进程数较多,即CPU负载不高,但I/O负载较高。可进一步定位是磁盘I/O还是网络I/O导致,比如是不是日志打印问题,jstack看看
配合iotop、vmstata查看