美团一面,你碰到过CPU 100%的情况吗?你是怎么处理的?

news2024/12/23 13:48:43

本文主要分为三部分

  1. 分析一下CPU 100%的常见原因

  2. CPU 100%如何排查

  3. 回答这个问题的一个参考答案

CPU被打满的常见原因

1. 死循环

在实际工作中,可能每个开发都写过死循环的代码。

死循环有两种:

  1. 在 while、for、forEach 循环中的死循环。

  2. 无限递归。

这两种情况,程序会不停地运行,使用寄存器保存循环次数或者递归深度,一直占用 cpu,导致 cpu 使用率飙升。

在使用 JDK1.7 时,还有些死循环比如多线程的环境下,往 HashMap 中 put 数据,可能会导致链表出现死循环

就会导致cpu不断飙高。

2.大量GC

我之前参与过餐饮相关的业务系统开发,当时我所在的团队是菜品的下游业务。

当时菜品系统有菜品的更新,会发kafka消息,我们系统订阅该topic,就能获取到最近更新的菜品数据。

同步菜品数据的功能,上线了一年多的时候,没有出现过什么问题。

但在某一天下午,我们收到了大量 CPU100% 的报警邮件。

追查原因之后发现,菜品系统出现了 bug,我们每次获取到的都是全量的菜品数据,并非增量的数据。

一次性获取的数据太多。

菜品修改还是比较频繁的,也就是说我们系统,会频繁地读取和解析大量的数据,导致 CPU 不断飙升。

其根本原因是频繁的full gc

3. 大量计算密集型任务

有时候,我们的业务系统需要实时计算数据,比如:电商系统中需要实时计算优惠后的最终价格。

或者需要在代码中,从一堆数据中,统计汇总出我们所需要的数据。

如果这个实时计算或者实时统计的场景,是一个非常耗时的操作,并且该场景的请求并发量还不小,就可能会导致 cpu 飙高。

因为实时计算需要消耗 cpu 资源,如果一直计算,就会一直消耗 cpu 资源。

4. 死锁

为了防止并发场景中,多个线程修改公共资源,导致的数据异常问题,很多时候我们会在代码中使用synchronized或者Lock加锁。

这样多个线程进入临界方法或者代码段时,需要竞争某个对象或者类的锁,只有抢到相应的锁,才能访问临界资源。其他的线程,则需要等待,拥有锁的线程释放锁,下一次可以继续竞争那把锁。

有些业务场景中,某段代码需要线程获取多把锁,才能完成业务逻辑。

但由于代码的 bug,或者释放锁的顺序不正确,可能会引起死锁的问题。

例如:

"pool-4-thread-1" prio=10 tid=0x00007f27bc11a000 nid=0x2ae9 waiting on condition [0x00007f2768ef9000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for  <0x0000000090e1d048> (a java.util.concurrent.locks.ReentrantLock$FairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)

比如线程 a 拥有锁 c,需要获取锁 d,才能完成业务逻辑。

而刚好此时线程 b 拥有锁 d,需要获取锁 c,才能完成业务逻辑。

线程 a 等待线程 b 释放锁,而线程 b 等待线程 a 释放锁,两个线程都持有对方需要的锁,无法主动释放,就会出现死锁问题。

死锁会导致 CPU 使用率飙升。

CPU被打满如何排查

1. 使用系统工具和JDK自带的jstack工具

第一步:使用top命令找出占用CPU最高的Java进程

首先,使用top命令确认是不是Java进程是罪魁祸首。Java进程要么是个后台任务,要么是个jar包,比如一个Spring Boot服务。

图片

假设发现占用CPU 99.7%的线程是Java进程,进程PID为13731。

第二步:找到占用CPU最高的线程

接下来,还是用top命令,只不过加一个参数-Hp,就是下面这样:

top -Hp 13731

H参数表示要显示线程级别的信息,p则表示指定的pid,也就是进程ID。执行之后,这个Java进程中占用线程占用CPU的情况就列出来了。假设占用CPU最高的那个线程PID为13756。

图片

第三步:保存线程堆栈信息

这就要用到JDK默认提供的一个工具——jstack。jstack用于生成Java进程的线程快照(thread dump)。线程快照是一个关于Java进程中所有线程当前状态的快照,包括每个线程的堆栈信息。通过分析线程快照,可以了解Java进程中各个线程的运行状态、锁信息等。

我们用jstack的目的是将那个占用CPU最高的线程的堆栈信息搞下来,然后进一步分析。使用命令jstack pid > out.log将某个进程的堆栈信息输出到out.log文件中。

jstack 13731 > thread_stack.log
第四步:在线程栈中查找罪魁祸首的线程

将13756转换为16进制,可以用在线进制转换工具直接转换,比如这个。转换结果为0x35bc。

然后在线程栈中,也就是上一步保存的那个thread_stack.log文件,查找这个16进制的线程ID(0x35bc)。

这样,我们就能看到需要的线程名称、线程状态,哪个方法的哪一行代码消耗了最多的CPU都很清楚了。

图片

2. 使用Arthas探测工具

Arthas是阿里开源的一款线上监控诊断产品,通过全局视角实时查看应用load、内存、GC、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。

安装Arthas

要使用Arthas,你需要先把它安装到你的目标服务器上。

  1. 下载jar包:

curl -O https://arthas.aliyun.com/arthas-boot.jar
  1. 启动Arthas服务:

java -jar arthas-boot.jar

启动之后,会列出当前这台服务器上的所有Java进程,选择你要排查的那个服务即可。出现arthas@之后表示已经启动,并成功attach到目标进程上。

图片

可以输入命令dashboard看一下实时面板,默认5秒刷新一次,在这个面板上能够看到线程、内存堆栈、GC和Runtime的基本信息。如果你用过VisualVM的话,操作界面与之类似。

找到占用CPU最高的线程

执行thread命令,这个命令会显示所有线程的信息,并且把CPU使用率高的线程排在前面。

这样,一眼就看出来了,第一个线程的CPU使用率高达99%。

图片

查看堆栈信息

使用thread ID获取堆栈信息,其实就是jstack pid相同的作用。通过前一步看到这个线程的ID是18,然后执行:

thread 18

图片

直接就看出来了出现问题的位置,比如TestController.java文件的high方法的第23行。然后可以进入代码查看具体问题。

参考答案

面试官:“你碰到过CPU 100%的情况吗?你是怎么处理的?”

生产环境如果cpu已经被打满了,不要一上来就说什么top,jstack,记住,真实的生产环境如果CPU已经要被打爆了的话

第一选择肯定是重启,并且如果你近段时间有发布的话,还要考虑是否可以回滚,保障生产环境的稳定性是最重要的

还有就是,如果CPU已经被打爆了,不管arthas还是jstack大概率也是执行不了的,jvm无法响应

我:“之前碰到过CPU被打满的情况,我们线上第一时间做了重启,在重启的过程中,我们去查了服务在那段时间的日志、链路、指标,没有发现特殊的异常。”

有时候CPU100&会伴随非常明显的日志、链路或者指标异常。例如:通过gc的指标发现,发现full gc的次数激增,或者发现内存的使用率很高,这个时候大概率是因为gc导致的cpu 100%。这个时候就不要再去jstack了,应该第一次时间查看堆dump文件,确认是哪个对象占用了大量内存

我:“当服务重启完成后,我们开始排查具体的原因。我们通过定期执行top命令,发现java进程的CPU的使用率确实在慢慢增加”

我:“接着,我通过top -Hp以及jstack命令拿到了应用里cpu使用率最高的那个线程的堆栈,通过分析堆栈最终定位到了具体的代码,是因为代码触发了一个临界值,进入了死循环”

下面这段代码是我实际工作碰到一个导致线上CPU 100%的代码:

public ShortUrlRandomSeed getAvailableSeed()  {
  MachineInfo machineInfo = UrlConverUtil.getMachineInfo();
  for (; ; ) {
    // 获取种子
    ShortUrlRandomSeed seed = shortUrlSeedService.getAvailableSeed(machineInfo);
    if (seed != null) {
      int influenceNum = shortUrlSeedService.updateSeedStatus(seed.getId());
      if (influenceNum > 0) {
        return seed;
      }
    }
  }
}

这段代码的作用是为了获取一个种子用于短链的生成,在项目上线之初预生成了接近21w个种子,这个代码在线上跑了3年了一直没有问题,直到去年的某一天,21w个种子用光了,seed一直为null,开始死循环,最终导致CPU 100%

还是我之前在文章中提到过的,记住一个原则:如果说面试有必杀技,那么一定是:真实的经历+具体的技术细节

美团一面,你碰到过CPU 100%的情况吗?你是怎么处理的?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1923681.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

期末成绩单怎么单独发给家长,这个小工具超简单!

随着期末考试的落幕&#xff0c;老师们再次迎来了成绩处理的高峰期。传统的成绩单分发方式不仅耗时&#xff0c;还容易出错。但如今&#xff0c;有了易查分小程序&#xff0c;这一过程变得简便而高效。 易查分小程序&#xff0c;一个专为教师和家长设计的便捷工具&#xff0c;让…

[ruby on rails]部署时候产生ActiveRecord::PreparedStatementCacheExpired错误的原因及解决方法

一、问题&#xff1a; 有时在 Postgres 上部署 Rails 应用程序时&#xff0c;可能会看到 ActiveRecord::PreparedStatementCacheExpired 错误。仅当在部署中运行迁移时才会发生这种情况。发生这种情况是因为 Rails 利用 Postgres 的缓存准备语句(PreparedStatementCache)功能来…

【Apache Doris】周FAQ集锦:第 10 期

【Apache Doris】周FAQ集锦&#xff1a;第 10 期 SQL问题数据操作问题运维常见问题其它问题关于社区 欢迎查阅本周的 Apache Doris 社区 FAQ 栏目&#xff01; 在这个栏目中&#xff0c;每周将筛选社区反馈的热门问题和话题&#xff0c;重点回答并进行深入探讨。旨在为广大用户…

算法力扣刷题记录 四十五【110.平衡二叉树】

前言 二叉树篇继续 记录 四十五【110.平衡二叉树】 一、题目阅读 给定一个二叉树&#xff0c;判断它是否是 平衡二叉树。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a;root [1,2,2,3,3…

【鸿蒙学习笔记】尺寸设置・width・height・size・margin・padding・

官方文档&#xff1a;尺寸设置 目录标题 width&#xff1a;设置组件自身的宽度height&#xff1a;设置组件自身的高度size&#xff1a;设置高宽尺寸margin&#xff1a;设置组件的外边距padding&#xff1a;设置组件的内边距 width&#xff1a;设置组件自身的宽度 参数为Length…

【零基础】学JS之APIS第三天

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…

10分钟快速了解神经网络(Neural Networks)

神经网络是深度学习算法的基本构建模块。神经网络是一种机器学习算法&#xff0c;旨在模拟人脑的行为。它由相互连接的节点组成&#xff0c;也称为人工神经元&#xff0c;这些节点组织成层次结构。 Source: victorzhou.com 神经网络与机器学习有何不同&#xff1f; 神经网络是…

电脑资料丢失不用慌,5招教你恢复数据

在数字化时代&#xff0c;电脑资料的安全与完整对我们而言至关重要。然而&#xff0c;生活中总有一些小插曲&#xff0c;如意外删除、系统故障或病毒攻击等&#xff0c;导致电脑上的重要资料消失得无影无踪。面对这种情况&#xff0c;我们往往感到焦虑和无助。今天&#xff0c;…

LabVIEW心电信号自动测试系统

开发了一种基于LabVIEW的心电信号自动测试系统&#xff0c;通过LabVIEW开发的上位机软件&#xff0c;实现对心电信号的实时采集、分析和自动化测试。系统包括心电信号采集模块、信号处理模块和自动化测试模块&#xff0c;能够高效、准确地完成心电信号的测量与分析。 硬件系统…

在 SwiftUI 中的作用域动画

文章目录 前言简单示例动画视图修饰符使用多个可动画属性使用 ViewBuilder总结 前言 从一开始&#xff0c;动画就是 SwiftUI 最强大的功能之一。你可以在 SwiftUI 中快速构建流畅的动画。唯一的缺点是每当我们需要运行多步动画或将动画范围限定到视图层次结构的特定部分时&…

网络规划设计师教程(第二版) pdf

网络规划设计师教程在网上找了很多都是第一版&#xff0c;没有第二版。 所以去淘宝买了第二版的pdf&#xff0c;与其自己独享不如共享出来&#xff0c;让大家也能看到。 而且这个pdf我已经用WPS扫描件识别过了&#xff0c;可以直接CtrlF搜索关键词&#xff0c;方便查阅。 链接…

股指期货存在的风险有哪些?

股指期货因其标的物的特殊性&#xff0c;其面临的风险类型十分复杂&#xff0c;主要面临的一般风险和特有风险如下&#xff1a; 一般风险 从风险是否可控的角度&#xff0c;可以划分为不可控风险和可控风险&#xff1b;从交易环节可分为代理风险、流动性风险、强制平仓风险&…

linux 安装redis 遇到问题解决方案

1.当下载了redis包时&#xff08;version&#xff1a;6.0.6&#xff09; 进入解压后的redis目录&#xff08;这里采用tar包安装&#xff09; 当执行make命令时 如果遇到如下情况&#xff1a; 查看当前服务起的gcc 版本&#xff1a;因为redis需要c编译器编译 gcc -v centos 7 …

使用亮数据代理IP+Python爬虫批量爬取招聘信息训练面试类AI智能体

本文目录 一、引言二、开发准备三、代码开发四、使用亮数据进行高效爬取4.1 为什么需要亮数据4.2 如何使用亮数据 五、使用数据训练AI智能体六、 总结 一、引言 在当今AI迅速发展的时代&#xff0c;招聘市场正经历着前所未有的变革。传统的招聘方式已难以满足双方的需求。AI智…

Transformer模型:Postion Embedding实现

前言 这是对上一篇WordEmbedding的续篇PositionEmbedding。 视频链接&#xff1a;19、Transformer模型Encoder原理精讲及其PyTorch逐行实现_哔哩哔哩_bilibili 上一篇链接&#xff1a;Transformer模型&#xff1a;WordEmbedding实现-CSDN博客 正文 先回顾一下原论文中对Posit…

如何巧妙运用百川工作手机微信行为监控 防范员工离职带走客户

在竞争日益激烈的商业环境中&#xff0c;企业最宝贵的资产莫过于忠诚的客户群体与高效协作的团队。然而&#xff0c;当团队中不可避免地出现人员流动时&#xff0c;如何有效防止客户资源流失&#xff0c;成为众多企业管理者面临的严峻挑战。百川工作手机&#xff0c;作为一款专…

基于Redisson 实现 Redis 分布式锁

代码示例&#xff1a; GetMapping("/testJmeter")public void testJmeter() {synchronized (this){int stock Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"))if (stock > 0) {int realStock stock - 1;stringRedisTemplate.opsFo…

【组件库】element-plus组件库

文章目录 0. 启动项目1. gc.sh 新增组件2. 本地验证(组件注册的方式)3. 官方文档修改3-1. 左侧菜单3-2 . 配置md文档3-3. 代码问题:文档修改----------------------------------------------4. 将naiveui的split 分割组件【 复制、迁移】到 element-ui-plus组件库4.1 naiveu…

Science Advances 仿生双模态触觉感知

研究背景 触觉感知在人类收集信息和接收周围环境反馈中扮演着至关重要的角色。随着人工智能的发展&#xff0c;具有类似人类感知能力的智能机器人受到越来越多的关注。现有的触觉传感器能够感知接触前的刺激和压力大小&#xff0c;但它们在区分物体类型、评估柔软度和量化杨氏…

go-高效处理应用程序数据

一、背景 大型的应用程序为了后期的排障、运营等&#xff0c;会将一些请求、日志、性能指标等数据保存到存储系统中。为了满足这些需求&#xff0c;我们需要进行数据采集&#xff0c;将数据高效的传输到存储系统 二、问题 采集服务仅仅针对某个需求开发&#xff0c;需要修改…