线上CPU100%?看看这篇是怎么排查的。
前言
作为后端开发工程师,当收到线上服务器CPU负载过高告警时,你会这么做?重启服务,忽略告警?不过在我看来一个合格的工程师是一定要定位到具体问题所在的,从而 fix 它。下面记录一下线上服务器 CPU 负载过高排查过程,把排查流程理清楚,以后遇到问题将会迅速定位到问题所在,快速解决。
什么样的场景会导致线上CPU负载过高?
代码层面常见的场景有:
- 程序陷入死循环,不停地消耗CPU
- 线程死锁,线程相互等待,导致假死状态,不停地消耗CPU
程序死循环场景
这里使用 JAVA 简单模拟程序死循环带来的系统高负载情况,代码如下:
/*** @program: easywits* @description: 并发下的 HashMap 测试....* @author: zhangshaolin* @create: 2018-12-19 15:27**/
public class HashMapMultiThread {static Map<String, String> map = new HashMap<>();public static class AddThread implements Runnable {int start = 0;public AddThread(int start) {this.start = start;}@Overridepublic void run() {//死循环,模拟CPU占用过高场景while (true) {for (int i = start; i < 100000; i += 4) {map.put(Integer.toString(i), Integer.toBinaryString(i));}}}public static void main(String[] args) throws InterruptedException {//线程并发对 HashMap 进行 put 操作 如果一切正常,则得到 map.size() 为100000//可能的结果://1. 程序正常,结果为100000//2. 程序正常,结果小于100000Thread thread1 = new Thread(new AddThread(0), "myTask-1");Thread thread2 = new Thread(new AddThread(1), "myTask-2");Thread thread3 = new Thread(new AddThread(2), "myTask-3");Thread thread4 = new Thread(new AddThread(3), "myTask-4");thread1.start();thread2.start();thread3.start();thread4.start();thread1.join();thread2.join();thread3.join();thread4.join();System.out.println(map.size());}}
}
复制代码
线程死锁场景
同样使用 JAVA 程序简单模拟线程死锁场景,代码如下:
/*** @program: easywits* @description: 死锁 demo ....* 1.两个线程里面分别持有两个Object对象:lock1和lock2。这两个lock作为同步代码块的锁;* 2.线程1的run()方法中同步代码块先获取lock1的对象锁,Thread.sleep(xxx),时间不需要太多,50毫秒差不多了,然后接着获取lock2的对象锁。* 这么做主要是为了防止线程1启动一下子就连续获得了lock1和lock2两个对象的对象锁* 3.线程2的run)(方法中同步代码块先获取lock2的对象锁,接着获取lock1的对象锁,当然这时lock1的对象锁已经被线程1锁持有,线程2肯定是要等待线程1释放lock1的对象锁的* <p>* 线程1″睡觉”睡完,线程2已经获取了lock2的对象锁了,线程1此时尝试获取lock2的对象锁,便被阻塞,此时一个死锁就形成了。* @author: zhangshaolin* @create: 2018-12-20 11:33**/
public class DeadLock {static Object lock1 = new Object();static Object lock2 = new Object();public static class Task1 implements Runnable {@Overridepublic void run() {synchronized (lock1) {System.out.println(Thread.currentThread().getName() + " 获得了第一把锁!!");try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lock2) {System.out.println(Thread.currentThread().getName() + " 获得了第二把锁!!");}}}}public static class Task2 implements Runnable {@Overridepublic void run() {synchronized (lock2) {System.out.println(Thread.currentThread().getName() + " 获得了第二把锁!!");synchronized (lock1) {System.out.println(Thread.currentThread().getName() + " 获得了第一把锁!!");}}}}public static void main(String[] args) throws InterruptedException {Thread thread1 = new Thread(new Task1(), "task-1");Thread thread2 = new Thread(new Task2(), "task-2");thread1.start();thread2.start();thread1.join();thread2.join();System.out.println(Thread.currentThread().getName() + " 执行结束!");}
}
复制代码
以上两种场景代码执行后,不出意外,系统CPU负载将会飙升,我的机器,4核CPU已经明显感觉到卡顿了,所以线上应该杜绝出现死循环代码。。
使用top
命令监控当前系统负载情况
执行第一种场景测试代码。
在 linux
命令行键入 top
指令后,就开始实时监控当前系统的负载信息,监控到的负载信息如下图所示:
从图中的监控信息可以快速大致的了解到,PID
为17499
的进程CPU负载高达328+%
,是一个 JAVA
程序。简单介绍下监控信息如下:
- PID:进程的ID
- USER:进程所有者
- PR:进程的优先级别,越小越优先被执行
- VIRT:进程占用的虚拟内存
- RES:进程占用的物理内存
- SHR:进程使用的共享内存
- S:进程的状态。S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值为负
- %CPU:进程占用CPU的使用率
- %MEM:进程使用的物理内存和总内存的百分比
- TIME+:该进程启动后占用的总的CPU时间,即占用CPU使用时间的累加值
在监控页面下 按键盘数字 1
可以看到每个CPU的负载情况,如下图:
可以看到开了四个线程,无限循环之后,我的机器中四个核心CPU,每颗负载接近百分百。
使用 top
命令监控进程中负载过高的线程
top -H -p pid
: 查看指定进程中每个线程的资源占用情况(每条线程占用CPU时间的百分比),监控结果如下图:
以上监控指令输出的指标针对的是某个进程中的线程,从图中看可以快速得出结论:四个 JAVA
线程CPU负载极高,线程ID分别为:17532
,17535
,17533
,17534
,注意这里打印出来的线程ID为十进制的哦!
根据进程pid
&&线程id
查看线程堆栈信息
jstack pid
:查看指定进程中线程的堆栈信息,这个命令最终会打印出指定进程的线程堆栈信息,而实际线上情况发生时,我们应当把快速把堆栈信息输出到日志文本中,保留日志信息,然后迅速先重启服务,达到临时缓解服务器压力的目的。jstack 17499 > ./threadDump.log
:将线程堆栈信息输出到当前目录下的 threadDump.log 文件。
注意:jstack 打印出的线程id号为十六进制,而 top 命令中打印出来的线程号为十进制,需要进行转换后,定位指定线程的堆栈信息
这里分析日志文件后,过滤出四个线程堆栈信息如下图:
从这四个线程执行的堆栈信息,很明显的看出:导致CPU飙升的程序正在执行 HashMap 的 put 操作。
友情提示:测试代码最好不要在公司的线上环境做测试哦!
更多原创文章会在公众号第一时间推送,欢迎扫码关注 张少林同学
线上CPU100%?看看这篇是怎么排查的。相关推荐
- 怎么解决线上CPU100%的问题
怎么解决线上CPU100%的问题 背景 Java服务,有时候会遇到CPU 100%的问题,对于这样的问题,我们如何快速定位并解决呢?一般会有如下几个步骤. 解决步骤 找到最耗CPU的进程 top 找到 ...
- 线上CPU100%排查
线上CPU100%排查 不知道在大家面试中,有没有遇到这个问题: 生产服务器上部署了几个java程序,突然出现了CPU100%的异常告警,你如何定位出问题呢? 这个问题分为两版回答! 高调版 对不起, ...
- 频繁gc是什么意思_一次性搞清楚线上CPU100%,频繁FullGC排查套路
原标题:一次性搞清楚线上CPU100%,频繁FullGC排查套路 " 处理过线上问题的同学基本上都会遇到系统突然运行缓慢,CPU 100%,以及 Full GC 次数过多的问题. 当然,这些 ...
- 线上服务器CPU占用率高如何排查定位问题?
(关联着看看这篇文章:https://blog.csdn.net/u011277123/article/details/103768939) 解决问题的能力以超高比例排名第一,这也是为什么很多面试过程 ...
- 线上服务Java进程假死快速排查、分析
线上服务Java进程假死快速排查.分析 最近我们有一台服务器上的Java进程总是在运行个两三天后就无法响应请求了,具体现象如下: 请求业务返回状态码502,查看进程还在,意味着Java进程假死,无法响 ...
- 原创|面试官:线上服务器CPU占用率高如何排查定位问题?
国外开发者平台 HankerRank 发布的 2018 年开发者技能调查报告中有一项关于"雇主最看重哪些核心能力"的调查,结果显示如下: 排名前几的比较受重视的能力分别为:解决问题 ...
- 服务器定位cpu高占用率代码php,面试官:线上服务器CPU占用率高如何排查定位问题?,...
面试官:线上服务器CPU占用率高如何排查定位问题?, 国外开发者平台 HankerRank 发布的 2018 年开发者技能调查报告中有一项关于"雇主最看重哪些核心能力"的调查,结果 ...
- 面试官:线上服务器CPU占用率高如何排查定位问题?
开发十年,就只剩下这套架构体系了!! 国外开发者平台 HankerRank 发布的 2018 年开发者技能调查报告中有一项关于"雇主最看重哪些核心能力"的调查,结果显示如下:  ...
- 线上CPU100%?看看这篇是怎么排查的!
前言 作为后端开发工程师,当收到线上服务器CPU负载过高告警时,你会这么做?重启服务,忽略告警?不过在我看来一个合格的工程师是一定要定位到具体问题所在的,从而 fix 它.下面记录一下线上服务器 CP ...
最新文章
- 修改Visual Studio 2010帮助位置
- NSURLSession使用说明及后台工作流程分析
- 实验二 建立基本的游戏场景
- 协同过滤——基于邻域的算法
- 如何解决JavaScript中0.1+0.2不等于0.3
- JVM调优总结(六)-分代垃圾回收详述2
- restfull api 接口 规范
- 瑞元双玻组件助力浙江多座分布式电站高效运行
- 三维点云学习(3)6- 实现K-Means
- JavaScript之String总汇
- 64位的windows server 2003运行IIS6运行32位的.NET程序
- 【大数据课程设计】出租车轨迹数据分析
- 学计算机编程有什么用,编程是什么 学习编程的好处
- angular 单击和双击事件分开
- 计算机网络基本原理pdf,自考计算机网络基本原理课程学习指引.pdf
- 高效准确处理scipy.misc 中imresize、imread导入错误问题
- 知识产权助力中国经济高质量发展广受认可
- 喝咖啡的好处和坏处好处
- 对于百度统计热力点击图的研究
- 《Android开发艺术探索》图书勘误
热门文章
- 内存泄漏分析 mat 使用 activity泄漏
- AppManager
- 【Android】使用AIDL传递用户自定义类型数据--附完整示例代码
- 对象的创建、内存布局和访问定位
- 火星坐标、百度坐标、WGS-84坐标相互转换及墨卡托投影坐标转经纬度JavaScript版...
- 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)
- 查看源代码Source not found及在eclipse中配置jdk的src.zip源代码
- linux /etc/profile和/etc/bashrc
- 一个http请求发送到后端的详细过程
- mvc3 之三 符号列表