生产机器CPU100%报警排查

背景

生产机器有完备的监控报警系统,例如我们公司的报警系统,可以配置多维度的报警指标:

收集线上服务机器的实时数据,一旦超过指标阈值即会出发报警。

每个集团都有类似其他的运维报警平台,机制大同小异。可配置的指标有cpu,内存,磁盘,oom,coredump等等。

 

问题

接到监控中台高频次的cpu-alarm报警通知,且线上多台机器连续报警。

生产机器CPU100%报警排查_第1张图片

线上服务出现问题,登陆线上机器进行排查。

 

排查方案

排查方案大体有以下几个步骤:

1、执行top命令

登陆发生cpu报警的机器,执行top命令:

top

执行之后的截图,可以看到PID为2192的进程在一直占用CPU。

top命令详解:

  • 首行load average:数据是每隔5秒钟检查一次活跃的进程数,按特定算法计算出的数值。数值除以逻辑CPU的数量得到结果,如果结果高于5,则说明系统已经在超负荷运转了。
  • PID:进程ID,进程的唯一标识符
  • USER:进程所有者的实际用户名。
  • PR:进程的调度优先级。这个字段的一些值是'rt'。这意味这这些进程运行在实时态。
  • NI:进程的nice值(优先级)。越小的值意味着越高的优先级。负值表示高优先级,正值表示低优先级
  • VIRT:进程使用的虚拟内存。进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
  • RES:驻留内存大小。驻留内存是任务使用的非交换物理内存大小。进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
  • SHR:SHR是进程使用的共享内存。共享内存大小,单位kb
  • S:进程的状态。它有以下不同的值:
    • D - 不可中断的睡眠态。
    • R – 运行态
    • S – 睡眠态
    • T – 被跟踪或已停止
    • Z – 僵尸态
  • %CPU:自从上一次更新时到现在任务所使用的CPU时间百分比。
  • %MEM:进程使用的可用物理内存百分比。
  • TIME+:任务启动后到现在所使用的全部CPU时间,精确到百分之一秒。
  • COMMAND:运行进程所使用的命令。进程名称(命令名/命令行)

2、执行top -Hp命令

top -Hp 2192    //查看2192进程下的所有线程占CPU的情况。找到占用CPU的线程

可以看到 8469、8470两个线程在占用CPU。

3、执行printf “0x%x” xxxx命令

printf “0x%x” 8469      //输出8469的十六进制

这个步骤的目的是输出进程号8469的十六进制数字,为接下来的查询做准备,因为虚拟机里面的进程堆栈信息中的进程号为十六进制单位

生产机器CPU100%报警排查_第2张图片

输出 8469的十六进制为:“0x2115”

4、执行jstack命令

jstack命令查询线程的堆栈信息:

/opt/java/bin/jstack 2192 | grep -30 0x2115

jstack命令格式:jstack 进程ID | grep -30 线程ID(16进制) 

生产机器CPU100%报警排查_第3张图片

截图中省略了中间的部分信息,从jstack堆栈信息中我们可以十分清楚的分析出当前线程正在执行什么方法,产生了什么问题。

如图中所示,线程卡在了MatchUtil.matchPart()这个方法的执行上,

Pattern$Curly.match0(Pattern.java:4274)

机器CPU一直消耗在Pattern正则表达式的处理上,处理正则表达式发生了死循环。

正则表达式是个双仞剑,如果大规模数据的校验最好不要使用正则,效率非常差。CPU的处理能力会全部耗费在处理正则上。当访问量突然增大后,CPU在短时间内LOAD值非常高。所以正则轻易不要用在大数据量或者并发访问较高的应用中。

另外正则表达式的编写一定要慎重,注意"回溯循环"问题,表达式要尽量写的简单,少写点括号,少写点+*等元字符,避免程序陷入死循环。

5、紧急处理方案

紧急处理方案,杀掉进程,重启服务

处理之后修改正则表达式,避免死循环问题发生。

总结

如此线上操作,整个流程下来可以定位到大部分CPU 报警的问题。

  • 1、top        //实时显示机器 process 的动态
  • 2、top -Hp 2192 //查看进程下的所有线程占CPU的情况, 找到占用cpu线程id
  • 3、printf “0x%x” 8469  //输出8469的十六进制 “0x2115”
  • 4、/opt/java/bin/jstack 2192 | grep -30 0x2115
  • 5、分析线程堆栈信息,找到问题根源。

另外线上机器监控诊断工具有一款非常优秀的产品:arthas,强烈推荐大家使用,灵活方便,功能强大,会在后续的文章中给大家介绍arthas的一些常用方法。

你可能感兴趣的:(liunx,java基础,java,线上问题排查,CPU报警)