Linux性能优化实战
倪朋飞
微软资深工程师,Kubernetes项目维护者
立即订阅
23395 人已学习
课程目录
已完结 64 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (2讲)
开篇词 | 别再让Linux性能问题成为你的绊脚石
免费
01 | 如何学习Linux性能优化?
CPU 性能篇 (13讲)
02 | 基础篇:到底应该怎么理解“平均负载”?
03 | 基础篇:经常说的 CPU 上下文切换是什么意思?(上)
04 | 基础篇:经常说的 CPU 上下文切换是什么意思?(下)
05 | 基础篇:某个应用的CPU使用率居然达到100%,我该怎么办?
06 | 案例篇:系统的 CPU 使用率很高,但为啥却找不到高 CPU 的应用?
07 | 案例篇:系统中出现大量不可中断进程和僵尸进程怎么办?(上)
08 | 案例篇:系统中出现大量不可中断进程和僵尸进程怎么办?(下)
09 | 基础篇:怎么理解Linux软中断?
10 | 案例篇:系统的软中断CPU使用率升高,我该怎么办?
11 | 套路篇:如何迅速分析出系统CPU的瓶颈在哪里?
12 | 套路篇:CPU 性能优化的几个思路
13 | 答疑(一):无法模拟出 RES 中断的问题,怎么办?
14 | 答疑(二):如何用perf工具分析Java程序?
内存性能篇 (8讲)
15 | 基础篇:Linux内存是怎么工作的?
16 | 基础篇:怎么理解内存中的Buffer和Cache?
17 | 案例篇:如何利用系统缓存优化程序的运行效率?
18 | 案例篇:内存泄漏了,我该如何定位和处理?
19 | 案例篇:为什么系统的Swap变高了(上)
20 | 案例篇:为什么系统的Swap变高了?(下)
21 | 套路篇:如何“快准狠”找到系统内存的问题?
22 | 答疑(三):文件系统与磁盘的区别是什么?
I/O 性能篇 (10讲)
23 | 基础篇:Linux 文件系统是怎么工作的?
24 | 基础篇:Linux 磁盘I/O是怎么工作的(上)
25 | 基础篇:Linux 磁盘I/O是怎么工作的(下)
26 | 案例篇:如何找出狂打日志的“内鬼”?
27 | 案例篇:为什么我的磁盘I/O延迟很高?
28 | 案例篇:一个SQL查询要15秒,这是怎么回事?
29 | 案例篇:Redis响应严重延迟,如何解决?
30 | 套路篇:如何迅速分析出系统I/O的瓶颈在哪里?
31 | 套路篇:磁盘 I/O 性能优化的几个思路
32 | 答疑(四):阻塞、非阻塞 I/O 与同步、异步 I/O 的区别和联系
网络性能篇 (13讲)
33 | 关于 Linux 网络,你必须知道这些(上)
34 | 关于 Linux 网络,你必须知道这些(下)
35 | 基础篇:C10K 和 C1000K 回顾
36 | 套路篇:怎么评估系统的网络性能?
37 | 案例篇:DNS 解析时快时慢,我该怎么办?
38 | 案例篇:怎么使用 tcpdump 和 Wireshark 分析网络流量?
39 | 案例篇:怎么缓解 DDoS 攻击带来的性能下降问题?
40 | 案例篇:网络请求延迟变大了,我该怎么办?
41 | 案例篇:如何优化 NAT 性能?(上)
42 | 案例篇:如何优化 NAT 性能?(下)
43 | 套路篇:网络性能优化的几个思路(上)
44 | 套路篇:网络性能优化的几个思路(下)
45 | 答疑(五):网络收发过程中,缓冲区位置在哪里?
综合实战篇 (13讲)
46 | 案例篇:为什么应用容器化后,启动慢了很多?
47 | 案例篇:服务器总是时不时丢包,我该怎么办?(上)
48 | 案例篇:服务器总是时不时丢包,我该怎么办?(下)
49 | 案例篇:内核线程 CPU 利用率太高,我该怎么办?
50 | 案例篇:动态追踪怎么用?(上)
51 | 案例篇:动态追踪怎么用?(下)
52 | 案例篇:服务吞吐量下降很厉害,怎么分析?
53 | 套路篇:系统监控的综合思路
54 | 套路篇:应用监控的一般思路
55 | 套路篇:分析性能问题的一般步骤
56 | 套路篇:优化性能问题的一般方法
57 | 套路篇:Linux 性能工具速查
58 | 答疑(六):容器冷启动如何性能分析?
加餐篇 (4讲)
加餐(一) | 书单推荐:性能优化和Linux 系统原理
加餐(二) | 书单推荐:网络原理和 Linux 内核实现
用户故事 | “半路出家 ”,也要顺利拿下性能优化!
用户故事 | 运维和开发工程师们怎么说?
结束语 (1讲)
结束语 | 愿你攻克性能难关
Linux性能优化实战
登录|注册

06 | 案例篇:系统的 CPU 使用率很高,但为啥却找不到高 CPU 的应用?

倪朋飞 2018-12-03
你好,我是倪朋飞。
上一节我讲了 CPU 使用率是什么,并通过一个案例教你使用 top、vmstat、pidstat 等工具,排查高 CPU 使用率的进程,然后再使用 perf top 工具,定位应用内部函数的问题。不过就有人留言了,说似乎感觉高 CPU 使用率的问题,还是挺容易排查的。
那是不是所有 CPU 使用率高的问题,都可以这么分析呢?我想,你的答案应该是否定的。
回顾前面的内容,我们知道,系统的 CPU 使用率,不仅包括进程用户态和内核态的运行,还包括中断处理、等待 I/O 以及内核线程等。所以,当你发现系统的 CPU 使用率很高的时候,不一定能找到相对应的高 CPU 使用率的进程
今天,我就用一个 Nginx + PHP 的 Web 服务的案例,带你来分析这种情况。

案例分析

你的准备

今天依旧探究系统 CPU 使用率高的情况,所以这次实验的准备工作,与上节课的准备工作基本相同,差别在于案例所用的 Docker 镜像不同。
本次案例还是基于 Ubuntu 18.04,同样适用于其他的 Linux 系统。我使用的案例环境如下所示:
机器配置:2 CPU,8GB 内存
预先安装 docker、sysstat、perf、ab 等工具,如 apt install docker.io sysstat linux-tools-common apache2-utils
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Linux性能优化实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(103)

  • sotey
    对老师膜拜!今天一早生产tomcat夯住了,16颗cpu全部98%以上,使用老师的方法加上java的工具成功定位到了问题线程和问题函数。

    作者回复: 举一反三动手实践的楷模😊 希望看到更多的人把这些思路用起来

    2018-12-03
    71
  • 好好学习
    perf record -ag -- sleep 2;perf report
    一部到位

    作者回复: 👍

    2018-12-10
    22
  • 每天晒白牙
    【D6补卡】
    如果碰到不好解释的CPU问题时,比如现象:
    通过top观察CPU使用率很高,但是看下面的进程的CPU使用率好像很正常,通过pidstat命令查看cpu也很正常。但通过top查看task数量不正常,处于R状态的进程是可疑点。

    首先要想到可能是短时间的应用导致的问题,如下面的两个:
    (1)应用里直接调用了其他二进制程序,这些程序通常运行时间比较短,通过top等工具发现不了
    (2)应用本身在不停地崩溃重启,而启动过程的资源初始化,很可能会占用很多CPU资源

    对于这类进程就需要 pstree 或execsnoop命令查找父进程,再从父进程的应用入手,找原因。
    我实战的问题:
    (1)centos的系统,发现通过 yum install pstress命令或其他命令,总是说没有匹配的软件包,这个很头疼
    ①pstress装不上可以尝试 yum install psmisc
    ②execsnoop这个命令我没有装上,想请教下老师如何解决这种yum install命令报没有匹配包的情况
    (2)然后就是通过perf命令只能看到十六进制符号,看不到具体函数名的问题,这个可以使用上篇文章中我的留言的方法,我在copy一份,供大家参考
    分析:当没有看到函数名,只看到十六进制时,说明perf无法找到待分析进程所依赖的库。
    解决办法:
    在容器外面把分析记录保存,到容器里面查看结果
    操作:
    (1)在centos系统上运行 perf record -g ,执行一会儿按ctrl+c停止
    (2)把生成的perf.data(通常文件生成在命令执行的当前目录下,当然可以通过find | grep perf.data或 find / -name perf.data查看路径)文件拷贝到容器里面分析:
    docker cp perf.data phpfpm:/tpm
    docker exec -i -t phpfpm bash
    cd /tmp/
    apt-get update && apt-get install -y linux-perf linux-tools procps
    perf_4.9 report
    这样就可以看到函数名了
    2018-12-05
    3
    15
  • bruceding
    http://blog.bruceding.com/420.html 这个是之前的优化经历,通过 perf + 火焰图,定位热点代码,结合业务和网络分析,最终确定问题原因

    作者回复: 赞,再加上APM定位就更简单了

    2019-02-11
    13
  • western
    感觉看侦探小说,遍看遍等老师说那句话——”真相只有一个”
    2018-12-06
    10
  • bruceding
    sar -w 或者 sar -w 1 也能直观的看到每秒生成线程或者进程的数量。Brendan Gregg 确实是这个领域的大师,贡献了很多的技术理念和实践经验。他的《性能之巅》 可以和本课对比着看,会有更多的理解。
    2019-02-12
    6
  • 划时代
    今天早上收到线上一台机器的CPU使用率告警邮件,马上登陆机器查看告警进程号的/proc情况,使用uptime、pidstat和top命令查当前运行情况,后面定位到是crontab定时任务中的程序引起负载过高。
    2018-12-04
    5
  • looperX
    Day03留言。
    Github上找到一个链接,里面有各种工具,包括execsnoop。
    2018-12-04
    1
    5
  • walker
    execsnoop这个工具在centos里找不到,有类似的代替品吗

    作者回复: 点击链接到github上。

    完全一样的工具应该没有,但可以基于内核追踪技术(比如BPF)来自己写一个。

    2018-12-03
    3
  • dexter
    环境已搭建好,但现在不知道怎么通过github链接来安装execsnoop
    2018-12-22
    1
    2
  • Griffin
    实际生产环境中的进程更多,stress藏在ps中根本不容易发现,pstree的结果也非常大。老师有空讲讲如何找到这些异常进程的方法和灵感。

    作者回复: 嗯嗯,这是一个模块,侧重于CPU的分析,后面还会讲磁盘、网络等等

    2018-12-09
    2
  • 阿蒙
    老师在某楼的回复中说 strace 没有统计功能,这里提一下,-c 可以统计某 pid 的系统调用次数,但确实没法对整个系统进行统计。
    2018-12-03
    2
  • 夜空中最亮的星(华仔)
    execsnoop
    这个工具没找到

    作者回复: 之前的链接有错误,已经修复了,可以点击链接跳过去

    2018-12-03
    2
  • 每天晒白牙
    【D6打卡】这几天回丈母娘家,没带电脑,没能实战,只能看文章了,回来后要补上
    2018-12-03
    2
  • 分析步骤:
    1,在top中,可见用户态cpu使用率很高,但未见相关有问题的进程;
    2,尝试pidstat 1 找出问题进程,无果;
    3,再次top,从load average 可见负载高,shift + f ,然后选择以s (进程状态)排序,按R倒序,可见running的进程主要就是几个stress进程,观察发现,running的stress进程的pid一直在变化;
    4,watch -d 'ps aux | grep stress | grep -v grep' 发现多个stress进程在不断生成,由R变S再变Z(由于watch的时间间隔是1秒,所以只是看到有多个stress进程,有的状态是R有的是S有的是Z,所以我推断其生命周期是如此)
    5,进程Pid再不断变化,有以下两个原因:
    5.1,进程在不断崩溃重启,如因为段错误,配置错误等,这时进程在退出后又被监控系统自动重启
    5.2,这些都是短进程,即在应用内部通过exec调用外部命令。这些命令一般只运行很短的时间就会结束,很难用时间间隔长的工具,如top去发现
    6,用pstress去找其父进程

    7,发现是php容器,故查看php源码
    # 拷贝源码到本地
    $ docker cp phpfpm:/app .
    # grep 查找看看是不是有代码在调用 stress 命令
    $ grep stress -r app

    8,从源代码中找相关字段

    9,stress -t 1 -d 1 是模拟IO压力的,但在之前的top中,未见%iowait异常;
    10,通过代码中的判断字段,手动赋值访问
    curl http://192.168.0.10:10000?verbose=1
    Server internal error: Array
    (
        [0] => stress: info: [19607] dispatching hogs: 0 cpu, 0 io, 0 vm, 1 hdd
        [1] => stress: FAIL: [19608] (563) mkstemp failed: Permission denied
        [2] => stress: FAIL: [19607] (394) <-- worker 19608 returned error 1
        [3] => stress: WARN: [19607] (396) now reaping child worker processes
        [4] => stress: FAIL: [19607] (400) kill error: No such process
        [5] => stress: FAIL: [19607] (451) failed run completed in 0s
    )
    11,从这里可以猜测,由于权限错误,大量的stress进程在启动时初始化失败,结合第4点,我认为CPU消耗在进程上下文切换,从vmstat可见cs由问题出现前的100多骤升并稳定维持在3000多
    [root@master ~]# vmstat 1
    procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
     r b swpd free buff cache si so bi bo in cs us sy id wa st
     9 0 0 6932288 2160 790400 0 0 20 24 44 71 8 5 87 0 0
     8 0 0 6932784 2160 790560 0 0 0 0 4027 3512 71 27 3 0 0
    11 0 0 6934920 2160 790488 0 0 0 0 4170 3646 72 28 1 0 0

    但pidstat -w |grep stress 却未见异常,因为同名进程一直在更换,所以用pidstat -w在这里是不太适用的
    [root@master ~]# pidstat -w 2 | grep stress
    09:55:29 AM 1 18583 0.50 0.50 stress
    09:55:29 AM 1 18584 0.50 0.50 stress
    09:55:29 AM 1 18586 0.50 0.00 stress
    。。。
    请问以上对吗?
    2019-05-01
    1
  • 汤🐠🥣昱
    1: 对于pidstat,vmstat,top无法定位到问题的时候。
    2: 可以选择perf record -g 记录。
    3: 用perf report查看是否可以定位到问题。
    4: 用pstree | grep [xx],这样定位到具体的调用方法里。
    5: 用grep [xx] -r [项目文件],找到具体代码位置。
    6: 查找源码,定位到具体位置,修改。
    2019-03-14
    1
  • 老师好,我在实验的过程中,在最后使用 perf record -ag 的时候,发现记录下来的值,其中 stress 并不是消耗 CPU 最猛的进程,而是swapper,不知道什么原因?碰到这种情况时,该如何继续排查下去?以下是我的 perf report
    Samples: 223K of event 'cpu-clock', Event count (approx.): 55956000000
      Children Self Command Shared Object Symbol
    + 11.54% 0.00% swapper [kernel.kallsyms] [k] cpu_startup_entry
    + 11.42% 0.00% swapper [kernel.kallsyms] [k] default_idle_call
    + 11.42% 0.00% swapper [kernel.kallsyms] [k] arch_cpu_idle
    + 11.42% 0.00% swapper [kernel.kallsyms] [k] default_idle
    + 11.05% 11.05% swapper [kernel.kallsyms] [k] native_safe_halt
    + 8.69% 0.00% swapper [kernel.kallsyms] [k] start_secondary
    + 4.36% 4.36% stress libc-2.24.so [.] 0x0000000000036387
    + 3.44% 0.00% php-fpm libc-2.24.so [.] 0xffff808406d432e1
    + 3.44% 0.00% php-fpm [unknown] [k] 0x6cb6258d4c544155
    + 3.43% 3.43% stress stress [.] 0x0000000000002eff
    + 3.20% 0.00% stress [kernel.kallsyms] [k] page_fault
    + 3.20% 0.00% stress [kernel.kallsyms] [k] do_page_fault
    + 3.15% 0.76% stress [kernel.kallsyms] [k] __do_page_fault

    作者回复: 嗯嗯 很好的问题。简单的说,swapper跟我们要分析的对象无关。这也是为什么我们不上来就用perf,而是先用其他方法缩小范围。我还会在答疑篇里解释swapper的作用

    2018-12-16
    3
    1
  • 400%cpu 150%user 3%nice 119%sys 127%idle 0% iow 0%irq 1% sirq 0%host
    PID USER PR NI VIRT RES SHR S[%CPU] %MEM TIME+ARGS
    4149 system 10 -10 1.8G 176M 113M 141 6.4 7:13.67
    4127 root 20 0 0 0 0 98.3 0 7:23.93
    老师你好,板卡上linux 系统好多工具无法使用,只能用top查看CPU使用率很高,
    uptime load average: 9.26 4.37 1.70

    目前分析到 用户空间占用CPU比较高,内核态的CPU占用也比较高。有没有什么可以进一步分析的工具或方法吗?感谢
    2018-12-04
    1
  • 阿成(Matthew)
    如果一个线程处于io状态,等待网络response,那么 这个线程。会被cpu调度的时候调用么?还是等到response有数据的时候,才会被调度到?
    2018-12-04
    1
  • kakasir
    因为开放面比较窄,老师后面提到的一些php,docker,ngix都比较陌生,新的虚拟机环境都需要安装,操作起来就困难重重,不过确实能通过案例领会解决问题的思路,还是会坚持下去
    2018-12-04
    1
收起评论
99+
返回
顶部