作者:jasonzxpan,腾讯 IEG 运营开发工程师

本文排查一个Linux 机器 CPU 毛刺问题,排查过程中不变更进程状态、也不会影响线上服务,最后还对 CPU 毛刺带来的风险进行了分析和验证。

本文中提到 CPU 统计和产生 core 文件的工具详见 simple-perf-tools 仓库。

问题描述

某服务所在机器统计显示,其 CPU 使用率在高峰时段出现毛刺。

暂时未收服务调用方的不良反馈。

初步排查

查看 CPU 1 分钟平均负载,发现 1 分钟平均负载有高有低,波动明显。说明机器上有些进程使用 CPU 波动很大。

登录机器排查进程,使用top指令。因为 CPU 会明显上升,重点怀疑使用 CPU 总时间高的进程,在打开 top 后,使用shift +t可以按照 CPU TIME 进行排序。

直观的看,有几个 spp_worker 相关的进程使用 CPU TIME 相对较高。

第一个进程因为启动的时间比较长,所以 CPU TIME 也比较大。可以使用下面的脚本,计算各个进程从各自拉起后 CPU 使用率:

uptime=`awk '{print $1}' /proc/uptime` # why is it too slow indocker?hertz=`zcat /proc/config.gz | grep CONFIG_HZ= |awk -F"=" '{print $2}'`awk -v uptime=$uptime -v hertz=$hertz -- '{printf("%d%s%11.3f", $1, $2, (100 *($14 + $15) / (hertz * uptime - $22)));}' /proc/*/stat 2> /dev/null | sort  -gr -k +3 | head -n 20

看到的也是这些 spp_worker 使用 CPU 相对要高一些:

选其中的一个 PID 为 45558 的 Worker 进程监控器 CPU 使用率:

可以发现其 CPU 大部分情况很低,但是在某一个时间点会升高,持续 1 秒左右。而且大部分时间是耗费在用户态,而非系统调用。

而《Linux Agent 采集项说明 - CPU 使用率》中描述的 CPU 使用率的采样策略为:

Linux Agent 每分钟会采集 4 次 15 秒内的 CPU 平均使用率。为了避免漏采集 CPU 峰值,网管 Agent 取这一分钟内四次采集的最大值上报。

因为采样可能采到高点或者低点,当 1 分钟内出现 CPU 飙升,则会表现为尖峰;如果四次都没有出现飙升,则表现为低谷。

至此,已经能确认是这批 Worker 进程引起了这种毛刺,但具体是哪部分代码有问题还需要进一步排查。

进一步排查

前边确认了没有太多的系统调用,所以不必使用strace工具。

使用perf工具

使用perf工具进行查看。具体的命令是perf top -p 45558,在低 CPU 使用率的时候:

但是当 CPU 飚上去的时候,perf采样的位置变成如下这样:

看一下红框的位置,可以发现可能是配置更新部分有问题,因为:

  • 这个地方 Protobuf 特别多的地方,在做更新的操作(有MergeFrom,有Delete)
  • 有大量的用到了std::map(有std::_Rb_tree,有字符串比较)

通过观察perf结果的方法,虽然能够猜测大计算量的位置,但是有两个不便之处:

  • 如果 CPU 高的情况发生概率很低,人为观察比较耗时
  • 不能明确的知道,具体在哪个文件的哪个函数

使用gcore

最初统计的时候,发现 CPU 高的情况会出现 1 秒多的时间,如果发现 CPU 高负载时,直接调用gcore {pid}的命令,可以保留堆栈信息,明确具体高负载的位置。

将使用 gcore 的指令,添加到统计工具中取,设置 CPU 上门先触发。

通过gdb看了几个 coredump 文件,发现堆栈和函数调用基本一致。可以明确的看到,大量的耗时发生在了AddActInfoV3这一函数中:

到此位置,我们明确了高计算量发生的具体位置。

风险点

CPU 突然飙升是否存在风险呢?是不是计算资源充足的时候,就不会有问题呢?

这个例子中,使用的是 SPP 微线程功能,每个 Worker 进程只启用一个线程。

如果仅仅是因为高计算量卡住 CPU,正常处理请求的逻辑将很难被调度到。这样势必会造成处理请求的延迟增大,甚至有超时返回的风险。

使用 spp 的cost_stat_tool工具

利用 spp 自带的统计工具印证这一风险点,查看 worker 处理前端请求时延统计信息,执行命令./cost_stat_tool -r 1:

上边的例子中,统计发生配置更新前后的 5 秒钟内,worker 处理的 231 个请求中,有 3 个请求的处理时间超过 500ms,远高于普通请求。

使用tcpdump抓包确认

因该服务没有打开详细的日志,想要进一步验证超过 500ms 的这些请求也是正常处理的请求,而非异常请求,可以通过抓包来分析。

tcpdump -i any tcp port 20391 -Xs0 -c 5000 -w service_spp.pcap

通过 wireshark 打开,需要过滤出返回时间 - 请求时间 > 500ms的相关请求。翻译成 wireshark 过滤器的表达式则是:

tcp.time_delta > 0.5 && tcp.dstport != 20391

过滤出一条符合条件的请求:

在该条记录上右键 -> Follow -> TCP Stream,可以查看该请求前后的 IP 包:

上边 4 个包分别是:

  1. +0ms 客户端发送请求至服务端
  2. +38ms 服务端回复 ACK,无数据
  3. +661ms 服务端发送返回至客户端
  4. +662ms 客户端回复 ACK

详细看了包中的内容为一条普通请求,逻辑简单,应该在 20ms 内返回。而此时的该进程使用 CPU 也确实为高负载的情况:

上述统计相互印证:

  • CPU 高时,正常的网络请求也会被阻塞住(回复 ACK 需要 38ms,低于 40ms,与TCP 延迟确认无关)
  • 平时只需要 20ms 能返回的请求,耗时了 660ms

CPU 突然飚高有风险,需要认真对待。

查看cpu使用率_腾讯游戏开发工程师:Linux 机器 CPU 毛刺问题排查相关推荐

  1. 腾讯游戏开发工程师:Linux 机器 CPU 毛刺问题排查

    以下内容转载自 https://www.toutiao.com/i6883739104001917444/ 原创腾讯技术工程2020-10-15 18:08:00 作者:jasonzxpan,腾讯 I ...

  2. 个人博客前端模板_腾讯前端开发工程师,教你极速搭建一个个人博客网站

    作者: bookerzhao,腾讯 CSIG web前端开发工程师 Github 为开源项目提供了用于静态页面展示的 Pages 服务,很多开发者都在上面托管了自己的静态网站和博客,不少开源项目的案例 ...

  3. 广州python开发工程师招聘_【广州游戏开发工程师招聘_最新广州游戏开发工程师招聘信息】-前程无忧...

    诚伯信息有限公司广州-天河区0.6-1.5万/月12-18 学历要求:本科|工作经验:1年|公司性质:民营公司|公司规模:5000-10000人 岗位职责1.与一流的开发团队协同工作,分析游戏各种玩法 ...

  4. cpu使用率_线程CPU使用率到底该如何计算?

    来源:公众号[鱼鹰谈单片机]作者:鱼鹰OspreyID   :emOsprey这篇笔记有如下内容:1.为什么需要计算各个线程的CPU使用率?2.该如何计算线程CPU使用率?3.FreeRTOS线程计算 ...

  5. cpu使用率_单片机里面的CPU使用率是什么鬼?

    打开电脑的任务管理器,看着跳动的CPU使用率,发现很舒服.每一个线程占用了多少CPU清清楚楚,也就能针对性的确认为啥你的电脑跑的慢了. 今天这篇笔记不讲每个任务(或线程)CPU的使用情况,而是单片机整 ...

  6. U3D游戏开发工程师正确入行姿势指南

    2021年,游戏圈上演了一场精彩绝伦的抢人大战.在上海游戏圈,年薪百万的人越来越多了. 据多名HR估算,在上海,过去一年TA.引擎.美术等稀缺岗位拟的薪资涨幅大概在20%-30%左右.某位圈内知名资深 ...

  7. 《学Unity的猫》——第十八集:Unity3D游戏开发工程师笔试刷题,皮皮收到面试邀请

    文章目录 18.1 皮皮收到面试邀请 18.2 面试题库相关网站 18.2.1 牛客网 18.2.2 领扣LintCode 18.2.3 力扣LeetCode 18.3 优质学习网站 18.3.1 菜 ...

  8. php开发工程师考试试卷,腾讯PHP开发工程师面试试卷

    1. 请对pOSIX风格和兼容perl风格两种正则表达式的主要函数进行类比说明 ereg preg_match ereg_replace preg_replace 2. 请说明在php.ini中saf ...

  9. ]网易游戏游戏开发工程师

    [面试题]网易游戏游戏开发工程师 2010-01-07 22:56 来自  空杯楠 网易游戏,武汉笔试,游戏开发工程师 1.一次考试,有25人参加,有ABC三题,每人至少会做一题,在不会做A的人中,会 ...

最新文章

  1. block的一些注意事项
  2. NanoPi NEO Air使用八:编写个简单的驱动和应用程序
  3. html表单文本框怎么输出函数值,如何获取用户输入的html文本表单字段传递给javascript函数的值?...
  4. Java 守护线程概述
  5. JDK的下载与安装eclipse的下载与安装
  6. 超大超长图片居中显示且放大缩小无影响
  7. 汇编语言-012(扩展加法指令ADC、带借位减法指令SBB、执行加法后进行ASCII调整指令、AAS 、AAM、AAD 、DAA指令将和数转成压缩十进制格式)
  8. 银辉机器人说明说_银辉儿童电动声控玩具 智能编程对话尊尼机器人 男孩礼物...
  9. mac内存空间不足怎么办?试试删除这几个文件夹!
  10. Linux系统解决SSH登录慢的详细步骤
  11. Git版本控制,一个本地子分支修改了代码(包括依赖pom)任何文件,然后本地主分支就自动更改为子分支的!这个问题这样解决
  12. 员工离职困扰?来看AI如何解决,基于人力资源分析的 ML 模型构建全方案 ⛵
  13. vm虚拟机获取ip地址
  14. (转)台式机华硕主板双显卡切换,怎么舒服怎么来
  15. 做SEO优化的目的到底是什么
  16. zbrush常用笔刷_教您在ZBrush中制作笔刷
  17. Python 求一元二次方程的解
  18. Action Chains类 使用鼠标操作使用方法
  19. CERC 2014 Outer space invaders (hnuoj13405)
  20. Edge浏览器访问特殊网站端口(如10080)出现ERR_UNSAFE_PORT解决办法

热门文章

  1. li在ie6 、ie7里莫名其妙的出现几px的margin
  2. SQL Server 备份与恢复之四:备份类型和选项
  3. HTML学习感想(4)【密码输入框、单选、复选框】
  4. 读书笔记:怪侠一枝梅 看后感
  5. IDEA spring boot maven架包
  6. 如何让SD-WAN超越MPLS?
  7. sdwan解决方案的分类—Vecloud
  8. 使用VS进行远程调试
  9. 写程序时如何使用日志
  10. JAVA-初步认识-第三章-if语句练习-星期和季节