故障排查类面经|服务器cpu占用过高怎么办?

近期有网友给我提了个建议:面试复盘和面试题讲解同步进行,分成两个不同的方向可能对大家的帮助会更大。其实我明白大家的意思,因为面试复盘主要是基于一场面试做复盘,比较宏观;面试题讲解是基于一个题来讲解,比较微观。所以我以后会分成两个专栏进行视频发布,面试题讲解我也会以文章的形式在公众号上发布!感谢大家支持!今天我来讲一道故障排查类面试题:服务器CPU占用过高该怎么办!
这道题其实我在某头部量化公司九坤量化的面试中被提及了,其实问这个问题主要是考察程序员的运维能力或者说程序员具不具备故障排查能力!接下来我就展开叙述一下!

1. 为什么CPU会飙高?

如果面试官问你为什么会飙高,那你就直接答原因,但是如果他问你的问题是服务器cpu占用过高怎么办?我建议你也聊一下,因为万事万物有因有果,回答问题也讲究一个前因后果!
CPU是整个电脑的核心计算资源,对于一个应用进程来说,CPU的最小执行单元是线程。导致 CPU 飙高的原因有以下两个:

  • CPU上下文切换过多。对于 CPU 来说,同一时刻下每个 CPU 核心只能运行一个线程,如果有多个线程要执行,CPU 只能通过上下文切换的方式来执行不同的线程。上下文切换需要做两个事情:保存运行线程的执行状态、让处于等待中的线程执行。这两个过程需要 CPU 执行内核相关指令实现状态保存,如果较多的上下文切换会占据大量CPU 资源,从而使得 CPU 无法去执行用户进程中的指令,导致响应速度下降。在 Java 中,文件 IO、网络 IO、锁等待、线程阻塞等操作都会造成线程阻塞从而触发上下文切换。
  • CPU资源的过度消耗。如果你的程序创建了大量线程,或者有线程一直占用CPU资源而无法释放(比如线程出现死循环等情况无法退出,也会一直占用CPU资源无法释放)也会导致cpu利用率过高!

2. 怎么排查解决问题?

要想排查解决cpu占用过高的问题,本质是要找到大量消耗cpu的线程,然后定位到相关的代码进行分析!其实这个题目更多考察的是你linux命令的掌握情况和线上运维能力。回答要点有两个:

  • 如何观察Linux服务器CPU占比;
  • 如何定位到产生问题的Java代码所在线程,判断出当前问题线程到底在执行什么方法。

a. 找到CPU消耗过高的进程id

通过top命令查看进程的cpu占用情况,运行top命令后再键入P(大写p)或者是 shift + p ,进程会按照CPU使用率排序,很显然我们就能拿到cpu消耗最高的进程id了。

b. 找到占用cpu最高的线程

一个进程中有多个线程,不可能所有线程都占着CPU不放。执行top -Hp pid命令,pid 就是前面拿到的进程id。然后键入P (大写p),线程按照CPU使用率排序。这样我们就能查到cpu占用最高的那个线程pid了!

top -Hp 进程id 

c. 查看线程的堆栈信息,定位相关代码

我们已经拿到了进程id和线程id,接下来我们只需要找到该线程的代码堆栈即可。
因为在堆栈信息中线程id是用16进制表示的,所以可以用python脚本输出一下该线程id的16进制表示!

printf "%xn" 线程id

jstack命令能够打印出当前所有java栈中的线程信息,其中必然包括出问题的线程。剩下我们要做的就是根据线程的id,找到这个线程正在执行的代码即可。

jstack 进程id | grep '你的16进制线程id' -C10 --color

最后我建议大家一定要熟悉jstack和top这两个命令的相关参数,因为面试官可能会拓展问一下这些命令的其他使用,比如我就被问到过:如果我要把jstack日志信息给存在一个文件里该怎么办?

jstack 进程id >> jstack.txt

3. 面试回答摘要

要想解决cpu飙高问题,先要明白cpu飙高的原因,CPU是整个电脑的核心计算资源,对于一个应用进程来说,CPU的最小执行单元是线程。导致 CPU 飙高的原因有以下两个:

  • 第一CPU上下文切换过多,对于 CPU 来说,同一时刻下每个 CPU 核心只能运行一个线程,如果有多个线程要执行,CPU 只能通过上下文切换的方式来执行不同的线程。这个过程需要 CPU 执行内核相关指令实现状态保存,如果较多的上下文切换会占据大量CPU 资源,从而使得 CPU 无法去执行用户进程中的指令,导致响应速度下降。在 Java 中,文件 IO、网络 IO、锁等待、线程阻塞等操作都会造成线程阻塞从而触发上下文切换。
  • 第二CPU资源的过度消耗。如果你的程序创建了大量线程,或者有线程一直占用CPU资源而无法释放(比如线程出现死循环等情况无法退出,也会一直占用CPU资源无法释放)也会导致cpu利用率过高!

要想排查解决cpu占用过高的问题,本质是要找到大量消耗cpu的线程,然后定位到相关的代码进行分析!

  • 第一步通过top命令查看进程的cpu占用情况,找到cpu消耗最高的进程id
  • 第二步执行top -Hp命令,进程id作为参数,找到占用CPU最多的线程id
  • 第三步将线程转为16进制,使用jstack命令,配合grep指令来查找该线程的堆栈信息,找到问题线程对应的代码,然后进一步分析原因。

原文始发于微信公众号(Java之禅):故障排查类面经|服务器cpu占用过高怎么办?

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/161303.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!