精华内容
下载资源
问答
  • Linux产品开发过程中,通常需要注意系统内存使用量,和评估单一进程的内存使用情况,便于我们选取合适的机器配置,来部署我们的产品。Linux本身提供了一些工具方便我们达成这些需求,查看进程实时资源top工具,更...

    在Linux产品开发过程中,通常需要注意系统内存使用量,和评估单一进程的内存使用情况,便于我们选取合适的机器配置,来部署我们的产品。

    Linux本身提供了一些工具方便我们达成这些需求,查看进程实时资源top工具,更详细的进程内存堆栈情况,pmap工具,Linux进程运行时状态信息也会保存在proc目录下,相应进程ID目录下,这里有很丰富的信息,先讨论进程内存。

    借助网上大部分人的说法,Linux系统在内存分配上:内存充足时,尽量使用内存来缓存一些文件,从而加快进程的运行速度,而当内存不足时,会通过相应的内存回收策略收回cache内存,供进程使用。

    虽然在Linux平台下做开发,但是对Linux内存管理并不熟悉,不过上述说法,可以通过下面的方法来验证:

    一、系统内存。

    在proc目录下的meminfo文件描述系统内存的使用情况,可用的物理内存=memfree+buffers+cached,下图是suse10 的情况:

    MemTotal 是全部物理内存,我的虚拟器配置的是1G内存,memfree+buffers+cached = 438752,大概还有430M可用,因为我的机器上只跑着apache和redis进程。

    当memfree不够时,内核会通过回写机制(pdflush线程)把cached和buffered内存回写到后备存储器,也可以通过手动方式显式释放cache内存

    echo 3 > /proc/sys/vm/drop_caches

    释放后,Buffers和Cached 表小了好多,MemFree变大了许多,memfree+buffers+cached三者和大约仍然是430M。

    二、进程内存

    在32位操作系统中,每个进程拥有4G的虚拟内存空间,其中0~3GB是每个进程的私有用户空间,这个空间对系统中其他进程是不可见的。3~4GB是linux内核空间,由系统所有的进程以及内核所共享的。通过访问/proc/{pid}/下相关文件,可以查看进程内存情况。

    如果进程内含有多个线程,多个线程共享一个进程的用户态虚拟地址空间,虚拟地址空间包含若干区域,主要有如下几个区域:

    1、当前执行文件的代码段,该代码段称为text段。

    2、执行文件的数据段,主要存储执行文件用到的全局变量,静态变量。(全局和static)

    3、存储全局变量和动态产生的数据的堆。(堆)

    4、用于保存局部变量和实现函数调用的栈。(栈)

    5、采用mmap方式映射到虚拟地址空间中的内存段

    这是我的机器上,redis 进程的情况,

    第一行:从r-xp可知其权限为只读、可执行,该段内存地址对应于执行文件的

    代码段,程序的代码段需加载到内存中才可以执行。由于其只读,不会

    被修改,所以在整个系统内共享。

    第二行:从rw-p可知其权限为可读写,不可执行,该段内存地址对应于执行文件的数据段,存放执行文件所用到的全局变量、静态变量。

    第三行:从rwxp可知其权限是可读写,可执行,地址空间向上增长,而且不对应文件,是堆段,进程使用malloc申请的内存放在堆段。每个进程只有一个堆段,不论是主进程,还是不同的线程申请的内存,都反映到到进程的堆段。堆段向上增长,最大可以增长到1GB的位置,即0x40000000,如果大于1GB,glibc将采用mmap的方式,为堆申请一块内存。

    第四行:是程序连接的共享库的内存地址。

    第五行:是以mmap方式映射的虚拟地址空间。

    第六、七行:是线程的栈区地址段,每个线程的栈大小都是16K。

    第八行:是进程的栈区。关于栈段,每个线程都有一个,如果进程中有多个线程,则包含多个栈段。

    三、当前系统总内存的统计

    1、进程占用的总内存可以通过上述maps表计算出来。

    2、当系统运行起来以后,会把应用层相关的文件挂载到tmpfs文件系统下,海思系统下这部分大概有13M左右,这部分内存是以cache方式统计出来的,但是这部分内存cache无法通过回收策略或者显式的调用释放掉。

    3、根文件系统ramdisk占用的内存。

    4、当前系统保留内存的大小,可以通过查看/proc/sys/vm/min_free_kbytes来获取或者修改此内存的大小。

    5、当然,当系统运行起来后,还应该留有一定的内存用于在硬盘读写时做cache或者网络负荷比较高时分配skb等,一般需要30M以上。

    四、对调试内存泄露类问题的一些启示

    当进程申请内存时,实际上是glibc中内置的内存管理器接收了该请求,随着进程申请内存的增加,内存管理器会通过系统调用陷入内核,从而为进程分配更多的内存。

    针对堆段的管理,内核提供了两个系统调用brk和mmap,brk用于更改堆顶地址,而mmap则为进程分配一块虚拟地址空间。

    当进程向glibc申请内存时,如果申请内存的数量大于一个阀值的时候,glibc会采用mmap为进程分配一块虚拟地址空间,而不是采用brk来扩展堆顶的指针。缺省情况下,此阀值是128K,可以通过函数来修改此值。

    #include

    Intmallopt(int param, int value)

    Param的取值分别为M_MMAP_THRESHOLD、M_MMAP_MAX。

    Value的取值是以字节为单位的。

    M_MMAP_THRESHOLD是glibc中申请大块内存阀值,大于该阀值的内存申请,内存管理器将使用mmap系统调用申请内存,如果小于该阀值的内存申请,内存管理器使用brk系统调用扩展堆顶指针。

    M_MMAP_MAX是该进程中最多使用mmap分配地址段的数量。

    如果在实际的调试过程中,怀疑某处发生了内存泄露,可以查看该进程的maps表,看进程的堆段或者mmap段的虚拟地址空间是否持续增加,如果是,说明很可能发生了内存泄露,如果mmap段虚拟地址空间持续增加,还可以看到各个段的虚拟地址空间的大小,从而可以确定是申请了多大的内存,对调试内存泄露类问题可以起到很好的定位作用。

    转自:http://blog.csdn.net/babykakaluo/article/details/9763605

    展开全文
  • 【摘要】本文主要介绍各种问题定位的工具,并结合案例分析问题。1. 背景有时候会遇到一些疑难杂症,并且监控插件并不能一眼立马发现问题的根源。这时候就需要登录服务器进一步深入分析问题的根源。那么分析问题需要...

    0d68b1e3bcf54400083af077b790e3fd.gif

    【摘要】本文主要介绍各种问题定位的工具,并结合案例分析问题。

    1. 背景

    有时候会遇到一些疑难杂症,并且监控插件并不能一眼立马发现问题的根源。这时候就需要登录服务器进一步深入分析问题的根源。那么分析问题需要有一定的技术经验积累,并且有些问题涉及到的领域非常广,才能定位到问题。所以,分析问题和踩坑非常锻炼一个人的成长和提升自我能力。如果我们有一套好的分析工具,那将是事半功倍,能够帮助大家快速定位问题,节省大家很多时间做更深入的事情。

    2. 说明

    本篇文章主要介绍各种问题定位的工具以及会结合案例分析问题。

    3. 分析问题的方法论

    套用5W2H方法,可以提出性能分析的几个问题

    1. What-现象是什么样的

    2. When-什么时候发生

    3. Why-为什么会发生

    4. Where-哪个地方发生的问题

    5. How much-耗费了多少资源

    6. How to do-怎么解决问题

    4. CPU

    4.1 说明

    针对应用程序,我们通常关注的是内核CPU调度器功能和性能。

    线程的状态分析主要是分析线程的时间用在什么地方,而线程状态的分类一般分为:

    a. on-CPU:执行中,执行中的时间通常又分为用户态时间user和系统态时间sys。

    b. off-CPU:等待下一轮上CPU,或者等待I/O、锁、换页等等,其状态可以细分为可执行、匿名换页、睡眠、锁、空闲等状态。

    如果大量时间花在CPU上,对CPU的剖析能够迅速解释原因;如果系统时间大量处于off-cpu状态,定位问题就会费时很多。但是仍然需要清楚一些概念:

    1、处理器

    2、核

    3、硬件线程

    4、CPU内存缓存

    5、时钟频率

    6、每指令周期数CPI和每周期指令数IPC

    7、CPU指令

    8、使用率

    9、用户时间/内核时间

    10、调度器

    11、运行队列

    12、抢占

    13、多进程

    14、多线程

    15、字长

    4.2 分析工具

    bd9d5c6e953d3763a41e217705040cab.png

    说明:

    1. uptime,vmstat,mpstat,top,pidstat只能查询到cpu及负载的的使用情况。

    2. perf可以跟着到进程内部具体函数耗时情况,并且可以指定内核函数进行统计,指哪打哪。

    4.3 使用方式

    //查看系统cpu使用情况

    top

    //查看所有cpu核信息

    mpstat -P ALL 1

    //查看cpu使用情况以及平均负载

    vmstat 1

    //进程cpu的统计信息

    pidstat -u 1 -p pid

    //跟踪进程内部函数级cpu使用情况

    perf top -p pid -e cpu-clock

    5. 内存

    5.1 说明

    内存是为提高效率而生,实际分析问题的时候,内存出现问题可能不只是影响性能,而是影响服务或者引起其他问题。同样对于内存有些概念需要清楚:

    1、主存

    2、虚拟内存

    3、常驻内存

    4、地址空间

    5、OOM

    6、页缓存

    7、缺页

    8、换页

    9、交换空间

    10、交换

    11、用户分配器libc、glibc、libmalloc和mtmalloc

    12、LINUX内核级SLUB分配器

    5.2 分析工具

    cea4e91ede734cd805955a3b90a60200.png

    说明:

    1、free,vmstat,top,pidstat,pmap只能统计内存信息以及进程的内存使用情况。

    2、valgrind可以分析内存泄漏问题。

    3、dtrace动态跟踪。需要对内核函数有很深入的了解,通过D语言编写脚本完成跟踪。

    5.3 使用方式

    //查看系统内存使用情况

    free -m

    //虚拟内存统计信息

    vmstat 1

    //查看系统内存情况

    top

    //1s采集周期,获取内存的统计信息

    pidstat -p pid -r 1

    //查看进程的内存映像信息

    pmap -d pid

    //检测程序内存问题

    valgrind --tool=memcheck --leak-check=full --log-file=./log.txt  ./程序名

    6. 磁盘IO

    6.1 说明

    磁盘通常是计算机最慢的子系统,也是最容易出现性能瓶颈的地方,因为磁盘离 CPU 距离最远而且 CPU 访问磁盘要涉及到机械操作,比如转轴、寻轨等。访问硬盘和访问内存之间的速度差别是以数量级来计算的,就像1天和1分钟的差别一样。要监测 IO 性能,有必要了解一下基本原理和 Linux 是如何处理硬盘和内存之间的 IO 的。

    在理解磁盘IO之前,同样我们需要理解一些概念,例如:

    1、文件系统

    2、VFS

    3、文件系统缓存

    4、页缓存page cache

    5、缓冲区高速缓存buffer cache

    6、目录缓存

    7、inode

    8、inode缓存

    9、noop调用策略

    6.2 分析工具

    4eabf0cfa2b5194007d1ba0c8b1589c6.png

    6.3 使用方式

    //查看系统io信息

    iotop

    //统计io详细信息

    iostat -d -x -k 1 10

    //查看进程级io的信息

    pidstat -d 1 -p  pid

    //查看系统IO的请求,比如可以在发现系统IO异常时,可以使用该命令进行调查,就能指定到底是什么原因导致的IO异常

    perf record -e block:block_rq_issue -ag

    ^C

    perf report

    7. 网络

    7.1 说明

    网络的监测是所有 Linux 子系统里面最复杂的,有太多的因素在里面,比如:延迟、阻塞、冲突、丢包等,更糟的是与 Linux 主机相连的路由器、交换机、无线信号都会影响到整体网络并且很难判断是因为 Linux 网络子系统的问题还是别的设备的问题,增加了监测和判断的复杂度。现在我们使用的所有网卡都称为自适应网卡,意思是说能根据网络上的不同网络设备导致的不同网络速度和工作模式进行自动调整。

    7.2 分析工具

    934f11a2b449c83ea0ebb03432ebe26f.png

    7.3 使用方式

    //显示网络统计信息

    netstat -s

    //显示当前UDP连接状况

    netstat -nu

    //显示UDP端口号的使用情况

    netstat -apu

    //统计机器中网络连接各个状态个数

    netstat -a | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

    //显示TCP连接

    ss -t -a

    //显示sockets摘要信息

    ss -s

    //显示所有udp sockets

    ss -u -a

    //tcp,etcp状态

    sar -n TCP,ETCP 1

    //查看网络IO

    sar -n DEV 1

    //抓包以包为单位进行输出

    tcpdump -i eth1 host 192.168.1.1 and port 80 

    //抓包以流为单位显示数据内容

    tcpflow -cp host 192.168.1.1

    8. 系统负载

    8.1 说明

    Load 就是对计算机干活多少的度量(WikiPedia:the system Load is a measure of the amount of work that a compute system is doing)简单的说是进程队列的长度。Load Average 就是一段时间(1分钟、5分钟、15分钟)内平均Load。

    8.2 分析工具

    c66a0bd59fb3b8c94bfa34e4443083c2.png

    8.3 使用方式

    //查看负载情况

    uptime

    top

    vmstat

    //统计系统调用耗时情况

    strace -c -p pid

    //跟踪指定的系统操作例如epoll_wait

    strace -T -e epoll_wait -p pid

    //查看内核日志信息

    dmesg

    9. 火焰图

    9.1 说明

    火焰图(Flame Graph是 Bredan Gregg 创建的一种性能分析图表,因为它的样子近似而得名。

    火焰图主要是用来展示 CPU的调用栈。

    y 轴表示调用栈,每一层都是一个函数。调用栈越深,火焰就越高,顶部就是正在执行的函数,下方都是它的父函数。

    x 轴表示抽样数,如果一个函数在 x 轴占据的宽度越宽,就表示它被抽到的次数多,即执行的时间长。注意,x 轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。

    火焰图就是看顶层的哪个函数占据的宽度最大。只要有”平顶”(plateaus),就表示该函数可能存在性能问题。颜色没有特殊含义,因为火焰图表示的是 CPU 的繁忙程度,所以一般选择暖色调。

    常见的火焰图类型有On-CPU、Off-CPU、Memory、Hot/Cold、Differential等等。

    9.2 安装依赖库

    //安装systemtap,默认系统已安装

    yum install systemtap systemtap-runtime

    //内核调试库必须跟内核版本对应,例如:uname -r 2.6.18-308.el5

    kernel-debuginfo-2.6.18-308.el5.x86_64.rpm

    kernel-devel-2.6.18-308.el5.x86_64.rpm

    kernel-debuginfo-common-2.6.18-308.el5.x86_64.rpm

    //安装内核调试库

    debuginfo-install --enablerepo=debuginfo search kernel

    debuginfo-install --enablerepo=debuginfo  search glibc

    9.3 安装

    git clone https://github.com/lidaohang/quick_location.git

    cd quick_location

    9.4 CPU级别火焰图

    cpu占用过高,或者使用率提不上来,你能快速定位到代码的哪块有问题吗?

    一般的做法可能就是通过日志等方式去确定问题。现在我们有了火焰图,能够非常清晰的发现哪个函数占用cpu过高,或者过低导致的问题。

    9.4.1 on-CPU

    cpu占用过高,执行中的时间通常又分为用户态时间user和系统态时间sys。

    使用方式:

    //on-CPU user

    sh ngx_on_cpu_u.sh pid

    //进入结果目录

    cd ngx_on_cpu_u

    //on-CPU kernel

    sh ngx_on_cpu_k.sh pid

    //进入结果目录

    cd ngx_on_cpu_k

    //开一个临时端口8088

    python -m SimpleHTTPServer 8088

    //打开浏览器输入地址

    127.0.0.1:8088/pid.svg

    DEMO:

    4e7890e4ec2a7252b42e68bd870a4efc.png

    DEMO火焰图:

    20efd7f82ec3a8e81b6bb39dcfee7b94.png

    9.4.2 off-CPU

    cpu过低,利用率不高。等待下一轮CPU,或者等待I/O、锁、换页等等,其状态可以细分为可执行、匿名换页、睡眠、锁、空闲等状态。

    使用方式:

    // off-CPU user

    sh ngx_off_cpu_u.sh pid

    //进入结果目录

    cd ngx_off_cpu_u

    //off-CPU kernel

    sh ngx_off_cpu_k.sh pid

    //进入结果目录

    cd ngx_off_cpu_k

    //开一个临时端口8088

    python -m SimpleHTTPServer 8088

    //打开浏览器输入地址

    127.0.0.1:8088/pid.svg

    官网DEMO:

    f4fcc9177b2fb8b4eff6c1f3facfa049.png

    9.5 内存级别火焰图

    如果线上程序出现了内存泄漏,并且只在特定的场景才会出现。这个时候我们怎么办呢?有什么好的方式和工具能快速的发现代码的问题呢?同样内存级别火焰图帮你快速分析问题的根源。

    使用方式:

    sh ngx_on_memory.sh pid

    //进入结果目录

    cd ngx_on_memory

    //开一个临时端口8088

    python -m SimpleHTTPServer 8088

    //打开浏览器输入地址

    127.0.0.1:8088/pid.svg

    官网DEMO:

    2b1a345e434a6c6cd400a22df3033a8a.png

    9.6 性能回退-红蓝差分火焰图

    你能快速定位CPU性能回退的问题么?如果你的工作环境非常复杂且变化快速,那么使用现有的工具是来定位这类问题是很具有挑战性的。当你花掉数周时间把根因找到时,代码已经又变更了好几轮,新的性能问题又冒了出来。主要可以用到每次构建中,每次上线做对比看,如果损失严重可以立马解决修复。

    通过抓取了两张普通的火焰图,然后进行对比,并对差异部分进行标色:红色表示上升,蓝色表示下降。差分火焰图是以当前(“修改后”)的profile文件作为基准,形状和大小都保持不变。因此你通过色彩的差异就能够很直观的找到差异部分,且可以看出为什么会有这样的差异。

    使用方式:

    cd quick_location

    //抓取代码修改前的profile 1文件

    perf record -F 99 -p pid -g -- sleep 30

    perf script > out.stacks1

    //抓取代码修改后的profile 2文件

    perf record -F 99 -p pid -g -- sleep 30

    perf script > out.stacks2

    //生成差分火焰图:

    ./FlameGraph/stackcollapse-perf.pl ../out.stacks1 > out.folded1

    ./FlameGraph/stackcollapse-perf.pl ../out.stacks2 > out.folded2

    ./FlameGraph/difffolded.pl out.folded1 out.folded2 | ./FlameGraph/flamegraph.pl > diff2.svg

    DEMO:

    963d3518f12d36e5bdc019ced4a01167.png

    cb46d9baec534edaf82de6eab5bf376b.png

    065f392dd0deb34985c903db1f254f4e.png

    DEMO红蓝差分火焰图:

    526c1bcc10f9f3ebc5dd60bd5efcfa50.png

    10. 案例分析

    10.1 接入层nginx集群异常现象

    通过监控插件发现在2017.09.25 19点nginx集群请求流量出现大量的499,5xx状态码。并且发现机器cpu使用率升高,目前一直持续中。

    10.2 分析nginx相关指标

    a) ****分析nginx请求流量:

    947722fd0677d7fd1e41b3e12b6de3c2.png

    结论:

    通过上图发现流量并没有突增,反而下降了,跟请求流量突增没关系。

    b) ****分析nginx响应时间

    df055ae9acbbc8d8fe31ba2a30565adb.png

    结论:

    通过上图发现nginx的响应时间有增加可能跟nginx自身有关系或者跟后端upstream响应时间有关系。

    c) ****分析nginx upstream响应时间

    dd554580b3155be8a087b60db1d4737a.png

    结论:

    通过上图发现nginx upstream 响应时间有增加,目前猜测可能后端upstream响应时间拖住nginx,导致nginx出现请求流量异常。

    10.3 分析系统cpu情况

    a) ****通过top观察系统指标

    top

    b5cc411fcb962f92456f3957dc4cc21b.png

    结论:

    发现nginx worker cpu比较高

    b) ****分析nginx进程内部cpu情况

    perf top -p pid

    694795f22e57f05dd02ffaaab60a4a2d.png

    结论:

    发现主要开销在free,malloc,json解析上面

    10.4 火焰图分析cpu

    a) ****生成用户态cpu火焰图

    //on-CPU user

    sh ngx_on_cpu_u.sh pid

    //进入结果目录

    cd ngx_on_cpu_u

    //开一个临时端口8088

    python -m SimpleHTTPServer 8088

    //打开浏览器输入地址

    127.0.0.1:8088/pid.svg

    b2abe94cf6d004865b3d8a63baaf9705.png

    结论:

    发现代码里面有频繁的解析json操作,并且发现这个json库性能不高,占用cpu挺高。

    10.5 案例总结

    **a) **分析请求流量异常,得出nginx upstream后端机器响应时间拉长

    **b) **分析nginx进程cpu高,得出nginx内部模块代码有耗时的json解析以及内存分配回收操作

    10.5.1 深入分析

    根据以上两点问题分析的结论,我们进一步深入分析。

    后端upstream响应拉长,最多可能影响nginx的处理能力。但是不可能会影响nginx内部模块占用过多的cpu操作。并且当时占用cpu高的模块,是在请求的时候才会走的逻辑。不太可能是upstram后端拖住nginx,从而触发这个cpu的耗时操作。

    10.5.2 解决方式

    遇到这种问题,我们优先解决已知的,并且非常明确的问题。那就是cpu高的问题。解决方式先降级关闭占用cpu过高的模块,然后进行观察。经过降级关闭该模块cpu降下来了,并且nginx请求流量也正常了。之所以会影响upstream时间拉长,因为upstream后端的服务调用的接口可能是个环路再次走回到nginx。

    4b7e672865a601f82389aadf745d6322.png

    628005add073b24c8b7978a44ad1e139.png

    Q Q咨询:450959328

     微信咨询:togogozhong

    8bb7139bc98c531a3e07ae7ca9bd2f2f.png
    展开全文
  • 关注我,你的眼睛会怀孕【摘要】本文主要介绍各种问题定位的工具,并结合案例分析问题。【作者】李航,多年的底层开发经验,在高性能nginx开发和分布式缓存redis cluster有着丰富的经验,目前从事分布式存储Ceph工作...

    关注我,你的眼睛会怀孕

    ce9da285fdf27cbe8cd1069ac0c01209.png【摘要】本文主要介绍各种问题定位的工具,并结合案例分析问题。

    【作者】李航,多年的底层开发经验,在高性能nginx开发和分布式缓存redis cluster有着丰富的经验,目前从事分布式存储Ceph工作,主要负责分布式Ceph系统。个人主要关注的技术领域:高性能Nginx开发、分布式缓存、分布式存储。

    1. 背景

    有时候会遇到一些疑难杂症,并且监控插件并不能一眼立马发现问题的根源。这时候就需要登录服务器进一步深入分析问题的根源。那么分析问题需要有一定的技术经验积累,并且有些问题涉及到的领域非常广,才能定位到问题。所以,分析问题和踩坑非常锻炼一个人的成长和提升自我能力。如果我们有一套好的分析工具,那将是事半功倍,能够帮助大家快速定位问题,节省大家很多时间做更深入的事情。

    2. 说明

    本篇文章主要介绍各种问题定位的工具以及会结合案例分析问题。

    3. 分析问题的方法论

    套用5W2H方法,可以提出性能分析的几个问题

    1. What-现象是什么样的

    2. When-什么时候发生

    3. Why-为什么会发生

    4. Where-哪个地方发生的问题

    5. How much-耗费了多少资源

    6. How to do-怎么解决问题

    4. CPU

    4.1 说明

    针对应用程序,我们通常关注的是内核CPU调度器功能和性能。

    线程的状态分析主要是分析线程的时间用在什么地方,而线程状态的分类一般分为:

    a. on-CPU:执行中,执行中的时间通常又分为用户态时间user和系统态时间sys。

    b. off-CPU:等待下一轮上CPU,或者等待I/O、锁、换页等等,其状态可以细分为可执行、匿名换页、睡眠、锁、空闲等状态。

    如果大量时间花在CPU上,对CPU的剖析能够迅速解释原因;如果系统时间大量处于off-cpu状态,定位问题就会费时很多。但是仍然需要清楚一些概念:

    1、处理器

    2、核

    3、硬件线程

    4、CPU内存缓存

    5、时钟频率

    6、每指令周期数CPI和每周期指令数IPC

    7、CPU指令

    8、使用率

    9、用户时间/内核时间

    10、调度器

    11、运行队列

    12、抢占

    13、多进程

    14、多线程

    15、字长

    4.2 分析工具

    99a625f3b8c60983deb8386258f68dc2.png

    说明:

    1. uptime,vmstat,mpstat,top,pidstat只能查询到cpu及负载的的使用情况。

    2. perf可以跟着到进程内部具体函数耗时情况,并且可以指定内核函数进行统计,指哪打哪。

    4.3 使用方式

    //查看系统cpu使用情况

    top

    //查看所有cpu核信息

    mpstat -P ALL 1

    //查看cpu使用情况以及平均负载

    vmstat 1

    //进程cpu的统计信息

    pidstat -u 1 -p pid

    //跟踪进程内部函数级cpu使用情况

    perf top -p pid -e cpu-clock

    5. 内存

    5.1 说明

    内存是为提高效率而生,实际分析问题的时候,内存出现问题可能不只是影响性能,而是影响服务或者引起其他问题。同样对于内存有些概念需要清楚:

    1、主存

    2、虚拟内存

    3、常驻内存

    4、地址空间

    5、OOM

    6、页缓存

    7、缺页

    8、换页

    9、交换空间

    10、交换

    11、用户分配器libc、glibc、libmalloc和mtmalloc

    12、LINUX内核级SLUB分配器

    5.2 分析工具

    a49614606ae0ba6b0009fb5fa9d53cb7.png

    说明:

    1、free,vmstat,top,pidstat,pmap只能统计内存信息以及进程的内存使用情况。

    2、valgrind可以分析内存泄漏问题。

    3、dtrace动态跟踪。需要对内核函数有很深入的了解,通过D语言编写脚本完成跟踪。

    5.3 使用方式

    //查看系统内存使用情况

    free -m

    //虚拟内存统计信息

    vmstat 1

    //查看系统内存情况

    top

    //1s采集周期,获取内存的统计信息

    pidstat -p pid -r 1

    //查看进程的内存映像信息

    pmap -d pid

    //检测程序内存问题

    valgrind --tool=memcheck --leak-check=full --log-file=./log.txt  ./程序名

    6. 磁盘IO

    6.1 说明

    磁盘通常是计算机最慢的子系统,也是最容易出现性能瓶颈的地方,因为磁盘离 CPU 距离最远而且 CPU 访问磁盘要涉及到机械操作,比如转轴、寻轨等。访问硬盘和访问内存之间的速度差别是以数量级来计算的,就像1天和1分钟的差别一样。要监测 IO 性能,有必要了解一下基本原理和 Linux 是如何处理硬盘和内存之间的 IO 的。

    在理解磁盘IO之前,同样我们需要理解一些概念,例如:

    1、文件系统

    2、VFS

    3、文件系统缓存

    4、页缓存page cache

    5、缓冲区高速缓存buffer cache

    6、目录缓存

    7、inode

    8、inode缓存

    9、noop调用策略

    6.2 分析工具

    1d99b96114c9cf6f1aa8deace190d725.png

    6.3 使用方式

    //查看系统io信息

    iotop

    //统计io详细信息

    iostat -d -x -k 1 10

    //查看进程级io的信息

    pidstat -d 1 -p  pid

    //查看系统IO的请求,比如可以在发现系统IO异常时,可以使用该命令进行调查,就能指定到底是什么原因导致的IO异常

    perf record -e block:block_rq_issue -ag

    ^C

    perf report

    7. 网络

    7.1 说明

    网络的监测是所有 Linux 子系统里面最复杂的,有太多的因素在里面,比如:延迟、阻塞、冲突、丢包等,更糟的是与 Linux 主机相连的路由器、交换机、无线信号都会影响到整体网络并且很难判断是因为 Linux 网络子系统的问题还是别的设备的问题,增加了监测和判断的复杂度。现在我们使用的所有网卡都称为自适应网卡,意思是说能根据网络上的不同网络设备导致的不同网络速度和工作模式进行自动调整。

    7.2 分析工具

    3c993caef6a47f7d81cd79f5c536a8a3.png

    7.3 使用方式

    //显示网络统计信息

    netstat -s

    //显示当前UDP连接状况

    netstat -nu

    //显示UDP端口号的使用情况

    netstat -apu

    //统计机器中网络连接各个状态个数

    netstat -a | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

    //显示TCP连接

    ss -t -a

    //显示sockets摘要信息

    ss -s

    //显示所有udp sockets

    ss -u -a

    //tcp,etcp状态

    sar -n TCP,ETCP 1

    //查看网络IO

    sar -n DEV 1

    //抓包以包为单位进行输出

    tcpdump -i eth1 host 192.168.1.1 and port 80 

    //抓包以流为单位显示数据内容

    tcpflow -cp host 192.168.1.1

    8. 系统负载

    8.1 说明

    Load 就是对计算机干活多少的度量(WikiPedia:the system Load is a measure of the amount of work that a compute system is doing)简单的说是进程队列的长度。Load Average 就是一段时间(1分钟、5分钟、15分钟)内平均Load。

    8.2 分析工具

    912a48b32f9250e6be018610a031ee95.png

    8.3 使用方式

    //查看负载情况

    uptime

    top

    vmstat

    //统计系统调用耗时情况

    strace -c -p pid

    //跟踪指定的系统操作例如epoll_wait

    strace -T -e epoll_wait -p pid

    //查看内核日志信息

    dmesg

    9. 火焰图

    9.1 说明

    火焰图(Flame Graph是 Bredan Gregg 创建的一种性能分析图表,因为它的样子近似 ?而得名。

    火焰图主要是用来展示 CPU的调用栈。

    y 轴表示调用栈,每一层都是一个函数。调用栈越深,火焰就越高,顶部就是正在执行的函数,下方都是它的父函数。

    x 轴表示抽样数,如果一个函数在 x 轴占据的宽度越宽,就表示它被抽到的次数多,即执行的时间长。注意,x 轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。

    火焰图就是看顶层的哪个函数占据的宽度最大。只要有”平顶”(plateaus),就表示该函数可能存在性能问题。颜色没有特殊含义,因为火焰图表示的是 CPU 的繁忙程度,所以一般选择暖色调。

    常见的火焰图类型有On-CPU、Off-CPU、Memory、Hot/Cold、Differential等等。

    9.2 安装依赖库

    //安装systemtap,默认系统已安装

    yum install systemtap systemtap-runtime

    //内核调试库必须跟内核版本对应,例如:uname -r 2.6.18-308.el5

    kernel-debuginfo-2.6.18-308.el5.x86_64.rpm

    kernel-devel-2.6.18-308.el5.x86_64.rpm

    kernel-debuginfo-common-2.6.18-308.el5.x86_64.rpm

    //安装内核调试库

    debuginfo-install --enablerepo=debuginfo search kernel

    debuginfo-install --enablerepo=debuginfo  search glibc

    9.3 安装

    git clone https://github.com/lidaohang/quick_location.git

    cd quick_location

    9.4 CPU级别火焰图

    cpu占用过高,或者使用率提不上来,你能快速定位到代码的哪块有问题吗?

    一般的做法可能就是通过日志等方式去确定问题。现在我们有了火焰图,能够非常清晰的发现哪个函数占用cpu过高,或者过低导致的问题。

    9.4.1 on-CPU

    cpu占用过高,执行中的时间通常又分为用户态时间user和系统态时间sys。

    使用方式:

    //on-CPU user

    sh ngx_on_cpu_u.sh pid

    //进入结果目录

    cd ngx_on_cpu_u

    //on-CPU kernel

    sh ngx_on_cpu_k.sh pid

    //进入结果目录

    cd ngx_on_cpu_k

    //开一个临时端口8088

    python -m SimpleHTTPServer 8088

    //打开浏览器输入地址

    127.0.0.1:8088/pid.svg

    DEMO:

    dbad89799606f747947129085f820f28.png

    DEMO火焰图:

    378535f3cce1c6375b0fbec26cc0859a.png

    9.4.2 off-CPU

    cpu过低,利用率不高。等待下一轮CPU,或者等待I/O、锁、换页等等,其状态可以细分为可执行、匿名换页、睡眠、锁、空闲等状态。

    使用方式:

    // off-CPU user

    sh ngx_off_cpu_u.sh pid

    //进入结果目录

    cd ngx_off_cpu_u

    //off-CPU kernel

    sh ngx_off_cpu_k.sh pid

    //进入结果目录

    cd ngx_off_cpu_k

    //开一个临时端口8088

    python -m SimpleHTTPServer 8088

    //打开浏览器输入地址

    127.0.0.1:8088/pid.svg

    官网DEMO:

    e17097911088b81e07e4b30b152759ed.png

    9.5 内存级别火焰图

    如果线上程序出现了内存泄漏,并且只在特定的场景才会出现。这个时候我们怎么办呢?有什么好的方式和工具能快速的发现代码的问题呢?同样内存级别火焰图帮你快速分析问题的根源。

    使用方式:

    sh ngx_on_memory.sh pid

    //进入结果目录

    cd ngx_on_memory

    //开一个临时端口8088

    python -m SimpleHTTPServer 8088

    //打开浏览器输入地址

    127.0.0.1:8088/pid.svg

    官网DEMO:

    97147ab134675a9f232403510fae2d65.png

    9.6 性能回退-红蓝差分火焰图

    你能快速定位CPU性能回退的问题么?如果你的工作环境非常复杂且变化快速,那么使用现有的工具是来定位这类问题是很具有挑战性的。当你花掉数周时间把根因找到时,代码已经又变更了好几轮,新的性能问题又冒了出来。主要可以用到每次构建中,每次上线做对比看,如果损失严重可以立马解决修复。

    通过抓取了两张普通的火焰图,然后进行对比,并对差异部分进行标色:红色表示上升,蓝色表示下降。差分火焰图是以当前(“修改后”)的profile文件作为基准,形状和大小都保持不变。因此你通过色彩的差异就能够很直观的找到差异部分,且可以看出为什么会有这样的差异。

    使用方式:

    cd quick_location

    //抓取代码修改前的profile 1文件

    perf record -F 99 -p pid -g -- sleep 30

    perf script > out.stacks1

    //抓取代码修改后的profile 2文件

    perf record -F 99 -p pid -g -- sleep 30

    perf script > out.stacks2

    //生成差分火焰图:

    ./FlameGraph/stackcollapse-perf.pl ../out.stacks1 > out.folded1

    ./FlameGraph/stackcollapse-perf.pl ../out.stacks2 > out.folded2

    ./FlameGraph/difffolded.pl out.folded1 out.folded2 | ./FlameGraph/flamegraph.pl > diff2.svg

    DEMO:

    05d39c6409a75e1b552bd9b309fe1036.png

    862ece631c45ca1ac2a536171d9937b8.png

    49f193718f4fa5cd25e9e067f01d8faf.png

    DEMO红蓝差分火焰图:

    babe405425e471307e4c81faea3deeed.png

    10. 案例分析

    10.1 接入层nginx集群异常现象

    通过监控插件发现在2017.09.25 19点nginx集群请求流量出现大量的499,5xx状态码。并且发现机器cpu使用率升高,目前一直持续中。

    10.2 分析nginx相关指标

    a) ****分析nginx请求流量:

    85039d7dcc0933d12adc7eaf7bb6b671.png

    结论:

    通过上图发现流量并没有突增,反而下降了,跟请求流量突增没关系。

    b) ****分析nginx响应时间

    636f4797ed36d318902d1bb6ea517dd1.png

    结论:

    通过上图发现nginx的响应时间有增加可能跟nginx自身有关系或者跟后端upstream响应时间有关系。

    c) ****分析nginx upstream响应时间

    eabab8f19fcdf3abe04845580cdf5412.png

    结论:

    通过上图发现nginx upstream 响应时间有增加,目前猜测可能后端upstream响应时间拖住nginx,导致nginx出现请求流量异常。

    10.3 分析系统cpu情况

    a) ****通过top观察系统指标

    top

    04616596ce5cc19a8568656ce2c72cd2.png

    结论:

    发现nginx worker cpu比较高

    b) ****分析nginx进程内部cpu情况

    perf top -p pid

    0111886f96d29b97cc9567e651da77e4.png

    结论:

    发现主要开销在free,malloc,json解析上面

    10.4 火焰图分析cpu

    a) ****生成用户态cpu火焰图

    //on-CPU user

    sh ngx_on_cpu_u.sh pid

    //进入结果目录

    cd ngx_on_cpu_u

    //开一个临时端口8088

    python -m SimpleHTTPServer 8088

    //打开浏览器输入地址

    127.0.0.1:8088/pid.svg

    05c22f6ec227546a8d3a32498b3ed183.png

    结论:

    发现代码里面有频繁的解析json操作,并且发现这个json库性能不高,占用cpu挺高。

    10.5 案例总结

    **a) **分析请求流量异常,得出nginx upstream后端机器响应时间拉长

    **b) **分析nginx进程cpu高,得出nginx内部模块代码有耗时的json解析以及内存分配回收操作

    10.5.1 深入分析

    根据以上两点问题分析的结论,我们进一步深入分析。

    后端upstream响应拉长,最多可能影响nginx的处理能力。但是不可能会影响nginx内部模块占用过多的cpu操作。并且当时占用cpu高的模块,是在请求的时候才会走的逻辑。不太可能是upstram后端拖住nginx,从而触发这个cpu的耗时操作。

    10.5.2 解决方式

    遇到这种问题,我们优先解决已知的,并且非常明确的问题。那就是cpu高的问题。解决方式先降级关闭占用cpu过高的模块,然后进行观察。经过降级关闭该模块cpu降下来了,并且nginx请求流量也正常了。之所以会影响upstream时间拉长,因为upstream后端的服务调用的接口可能是个环路再次走回到nginx。

    参考资料:

    1、http://www.brendangregg.com/index.html

    2、http://www.brendangregg.com/FlameGraphs/cpuflamegraphs.html

    3、http://www.brendangregg.com/FlameGraphs/memoryflamegraphs.html

    4、http://www.brendangregg.com/FlameGraphs/offcpuflamegraphs.html

    5、http://www.brendangregg.com/blog/2014-11-09/differential-flame-graphs.html

    6、https://github.com/openresty/openresty-systemtap-toolkit

    7、https://github.com/brendangregg/FlameGraph

    8、https://www.slideshare.net/brendangregg/blazing-performance-with-flame-graphs

    原题:运维必备的技能——问题故障定位

    1

    end

    来源:twt企业IT社区

    年度热文

    6db46dc8d7154018315c0aa6fddb96dc.png

    【收藏】华为5700系列交换机常用配置示例

    【科普】为什么ip地址通常以192.168开头?

    【干货】图文并茂磁盘阵列RAID详解

    【教程】手把手zabbix安装教程

    【实验】小型企业网三层架构

    【干货】运维常用的17款监控系统

    【热点】又一起删库跑路事件!公司损失近 10 亿

    干货】TCP协议详解

    【技术】老司机网络排障实例

    【必看】网工常见10大问题及解决方法

    【热点】11天竣工交付,火神山医院背后的网络建设

    【必看】中型企业网络构建——OSPF区域划分(特殊域)

    【必看】局域网ip地址不够用怎么办?

    【基础】Ansible 自动化运维工具简单入门

    【收藏】cisco设备报错消息汇总

    【干货】TCP连接的状态详解以及故障排查

    【必看】华为交换机型号解读

    【必看】常见23种网络速度变慢的解决方法



    24b0d93fc8aad3c9564864634e810596.png

    系统集成/认证培训

    买设备,找我们

    IT维保,找我们

    IT培训,找我们

    展开全文
  • 这时候就需要登录服务器进一步深入分析问题的根源。那么分析问题需要有一定的技术经验积累,并且有些问题涉及到的领域非常广,才能定位到问题。所以,分析问题和踩坑是非常锻炼一个人的成长和提升自我能力。如果我们...

    8d3120928abdc0813c8abe9891a6c269.png

    1. 背景

    有时候会遇到一些疑难杂症,并且监控插件并不能一眼立马发现问题的根源。这时候就需要登录服务器进一步深入分析问题的根源。那么分析问题需要有一定的技术经验积累,并且有些问题涉及到的领域非常广,才能定位到问题。所以,分析问题和踩坑是非常锻炼一个人的成长和提升自我能力。如果我们有一套好的分析工具,那将是事半功倍,能够帮助大家快速定位问题,节省大家很多时间做更深入的事情。

    2. 说明

    本篇文章主要介绍各种问题定位的工具以及会结合案例分析问题。

    3. 分析问题的方法论

    套用5W2H方法,可以提出性能分析的几个问题
    • What-现象是什么样的
    • When-什么时候发生
    • Why-为什么会发生
    • Where-哪个地方发生的问题
    • How much-耗费了多少资源
    • How to do-怎么解决问题

    4. cpu

    4.1 说明

    针对应用程序,我们通常关注的是内核CPU调度器功能和性能。

    线程的状态分析主要是分析线程的时间用在什么地方,而线程状态的分类一般分为:

    1. on-CPU:执行中,执行中的时间通常又分为用户态时间user和系统态时间sys。

    2. off-CPU:等待下一轮上CPU,或者等待I/O、锁、换页等等,其状态可以细分为可执行、匿名换页、睡眠、锁、空闲等状态。

    如果大量时间花在CPU上,对CPU的剖析能够迅速解释原因;如果系统时间大量处于off-cpu状态,定位问题就会费时很多。但是仍然需要清楚一些概念:
    • 处理器
    • 硬件线程
    • CPU内存缓存
    • 时钟频率
    • 每指令周期数CPI和每周期指令数IPC
    • CPU指令
    • 使用率
    • 用户时间/内核时间
    • 调度器
    • 运行队列
    • 抢占
    • 多进程
    • 多线程
    • 字长

    4.2 分析工具

    4e4752212da96346060588dfa3ed2dc3.png

    说明:
    • uptime,vmstat,mpstat,top,pidstat 只能查询到cpu及负载的的使用情况。
    • perf可以跟着到进程内部具体函数耗时情况,并且可以指定内核函数进行统计,指哪打哪。

    4.3 使用方式

    //查看系统cpu使用情况top//查看所有cpu核信息mpstat -P ALL 1//查看cpu使用情况以及平均负载vmstat 1//进程cpu的统计信息pidstat -u 1 -p pid//跟踪进程内部函数级cpu使用情况 perf top -p pid -e cpu-clock

    5. 内存

    5.1 说明

    内存是为提高效率而生,实际分析问题的时候,内存出现问题可能不只是影响性能,而是影响服务或者引起其他问题。同样对于内存有些概念需要清楚:
    • 主存
    • 虚拟内存
    • 常驻内存
    • 地址空间
    • OOM
    • 页缓存
    • 缺页
    • 换页
    • 交换空间
    • 交换
    • 用户分配器libc、glibc、libmalloc和mtmalloc
    • LINUX内核级SLUB分配器

    5.2 分析工具

    9585ce7a17c4c64655a6c8d852a3b212.png

    说明:

    • free,vmstat,top,pidstat,pmap只能统计内存信息以及进程的内存使用情况。

    • valgrind 可以分析内存泄漏问题。

    • dtrace 动态跟踪。需要对内核函数有很深入的了解,通过D语言编写脚本完成跟踪。

    5.3 使用方式

    //查看系统内存使用情况free -m//虚拟内存统计信息vmstat 1//查看系统内存情况top//1s采集周期,获取内存的统计信息pidstat -p pid -r 1//查看进程的内存映像信息pmap -d pid//检测程序内存问题valgrind --tool=memcheck --leak-check=full --log-file=./log.txt  ./程序名

    6. 磁盘IO

    6.1 说明

    磁盘通常是计算机最慢的子系统,也是最容易出现性能瓶颈的地方,因为磁盘离 CPU 距离最远而且 CPU 访问磁盘要涉及到机械操作,比如转轴、寻轨等。访问硬盘和访问内存之间的速度差别是以数量级来计算的,就像1天和1分钟的差别一样。要监测 IO 性能,有必要了解一下基本原理和 Linux 是如何处理硬盘和内存之间的 IO 的。

    在理解磁盘IO之前,同样我们需要理解一些概念,例如:

    • 文件系统
    • VFS
    • 文件系统缓存
    • 页缓存page cache
    • 缓冲区高速缓存buffer cache
    • 目录缓存
    • inode
    • inode缓存
    • noop调用策略

    6.2 分析工具

    715009d8040dd3d09acbe89e362248c9.png

    6.3 使用方式

    //查看系统io信息iotop//统计io详细信息iostat -d -x -k 1 10//查看进程级io的信息pidstat -d 1 -p  pid//查看系统IO的请求,比如可以在发现系统IO异常时,可以使用该命令进行调查,就能指定到底是什么原因导致的IO异常perf record -e block:block_rq_issue -ag^Cperf report

    7. 网络

    7.1 说明

    网络的监测是所有 Linux 子系统里面最复杂的,有太多的因素在里面,比如:延迟、阻塞、冲突、丢包等,更糟的是与 Linux 主机相连的路由器、交换机、无线信号都会影响到整体网络并且很难判断是因为 Linux 网络子系统的问题还是别的设备的问题,增加了监测和判断的复杂度。现在我们使用的所有网卡都称为自适应网卡,意思是说能根据网络上的不同网络设备导致的不同网络速度和工作模式进行自动调整。

    7.2 分析工具

    5d090d0f8e2c43e57bc30c17e6e353a1.png

    7.3 使用方式

    //显示网络统计信息netstat -s//显示当前UDP连接状况netstat -nu//显示UDP端口号的使用情况netstat -apu//统计机器中网络连接各个状态个数netstat -a | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'//显示TCP连接ss -t -a//显示sockets摘要信息ss -s//显示所有udp socketsss -u -a//tcp,etcp状态sar -n TCP,ETCP 1//查看网络IOsar -n DEV 1//抓包以包为单位进行输出tcpdump -i eth1 host 192.168.1.1 and port 80 //抓包以流为单位显示数据内容tcpflow -cp host 192.168.1.1

    8. 系统负载

    8.1 说明

    Load 就是对计算机干活多少的度量(WikiPedia:the system Load is a measure of the amount of work that a compute system is doing)简单的说是进程队列的长度。Load Average 就是一段时间(1分钟、5分钟、15分钟)内平均Load。

    8.2 分析工具

    710e6576c5cc0fd411f7cb3eb44eaba3.png

    8.3 使用方式

    //查看负载情况uptimetopvmstat//统计系统调用耗时情况strace -c -p pid//跟踪指定的系统操作例如epoll_waitstrace -T -e epoll_wait -p pid//查看内核日志信息dmesg

    9. 火焰图

    9.1 说明

    火焰图(Flame Graph是 Bredan Gregg 创建的一种性能分析图表,因为它的样子近似 ?而得名。火焰图主要是用来展示 CPU的调用栈。y 轴表示调用栈,每一层都是一个函数。调用栈越深,火焰就越高,顶部就是正在执行的函数,下方都是它的父函数。x 轴表示抽样数,如果一个函数在 x 轴占据的宽度越宽,就表示它被抽到的次数多,即执行的时间长。注意,x 轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。火焰图就是看顶层的哪个函数占据的宽度最大。只要有”平顶”(plateaus),就表示该函数可能存在性能问题。颜色没有特殊含义,因为火焰图表示的是 CPU 的繁忙程度,所以一般选择暖色调。

    常见的火焰图类型有 On-CPU、Off-CPU、Memory、Hot/Cold、Differential等等。

    9.2 安装依赖库

    //安装systemtap,默认系统已安装yum install systemtap systemtap-runtime//内核调试库必须跟内核版本对应,例如:uname -r 2.6.18-308.el5kernel-debuginfo-2.6.18-308.el5.x86_64.rpmkernel-devel-2.6.18-308.el5.x86_64.rpmkernel-debuginfo-common-2.6.18-308.el5.x86_64.rpm//安装内核调试库debuginfo-install --enablerepo=debuginfo search kerneldebuginfo-install --enablerepo=debuginfo  search glibc

    9.3 安装

    git clone https://github.com/lidaohang/quick_location.gitcd quick_location

    9.4 CPU级别火焰图

    cpu占用过高,或者使用率提不上来,你能快速定位到代码的哪块有问题吗?

    一般的做法可能就是通过日志等方式去确定问题。现在我们有了火焰图,能够非常清晰的发现哪个函数占用cpu过高,或者过低导致的问题。

    9.4.1 on-CPU

    cpu占用过高,执行中的时间通常又分为用户态时间user和系统态时间sys。使用方式:
    //on-CPU usersh ngx_on_cpu_u.sh pid//进入结果目录 cd ngx_on_cpu_u//on-CPU kernelsh ngx_on_cpu_k.sh pid//进入结果目录 cd ngx_on_cpu_k//开一个临时端口 8088 python -m SimpleHTTPServer 8088//打开浏览器输入地址127.0.0.1:8088/pid.svg
    DEMO:
    #include #include void foo3(){  }void foo2(){    int i;    for(i=0 ; i < 10; i++)           foo3();}void foo1(){    int i;  for(i = 0; i< 1000; i++)      foo3();}int main(void){    int i;    for( i =0; i< 1000000000; i++) {          foo1();          foo2();    }}

    DEMO火焰图:

    12fb5b321ae6c4cdfb96fe7982f24a73.png

    9.4.2 off-CPU

    cpu过低,利用率不高。等待下一轮CPU,或者等待I/O、锁、换页等等,其状态可以细分为可执行、匿名换页、睡眠、锁、空闲等状态。

    使用方式:

    // off-CPU usersh ngx_off_cpu_u.sh pid//进入结果目录cd ngx_off_cpu_u//off-CPU kernelsh ngx_off_cpu_k.sh pid//进入结果目录cd ngx_off_cpu_k//开一个临时端口8088python -m SimpleHTTPServer 8088//打开浏览器输入地址127.0.0.1:8088/pid.svg

    官网DEMO:

    dd0ca0f16e6f123f7b84bc8e93df6c4c.png

    9.5 内存级别火焰图

    如果线上程序出现了内存泄漏,并且只在特定的场景才会出现。这个时候我们怎么办呢?有什么好的方式和工具能快速的发现代码的问题呢?同样内存级别火焰图帮你快速分析问题的根源。

    使用方式:

    sh ngx_on_memory.sh pid//进入结果目录cd ngx_on_memory//开一个临时端口8088python -m SimpleHTTPServer 8088//打开浏览器输入地址127.0.0.1:8088/pid.svg

    官网DEMO:

    99a6d49ff3d85f4963be2ce719d66dd7.png

    9.6 性能回退-红蓝差分火焰图

    你能快速定位CPU性能回退的问题么?如果你的工作环境非常复杂且变化快速,那么使用现有的工具是来定位这类问题是很具有挑战性的。当你花掉数周时间把根因找到时,代码已经又变更了好几轮,新的性能问题又冒了出来。主要可以用到每次构建中,每次上线做对比看,如果损失严重可以立马解决修复。

    通过抓取了两张普通的火焰图,然后进行对比,并对差异部分进行标色:红色表示上升,蓝色表示下降。差分火焰图是以当前(“修改后”)的profile文件作为基准,形状和大小都保持不变。因此你通过色彩的差异就能够很直观的找到差异部分,且可以看出为什么会有这样的差异。

    使用方式:

    cd quick_location//抓取代码修改前的profile 1文件perf record -F 99 -p pid -g -- sleep 30perf script > out.stacks1//抓取代码修改后的profile 2文件perf record -F 99 -p pid -g -- sleep 30perf script > out.stacks2//生成差分火焰图:./FlameGraph/stackcollapse-perf.pl ../out.stacks1 > out.folded1./FlameGraph/stackcollapse-perf.pl ../out.stacks2 > out.folded2./FlameGraph/difffolded.pl out.folded1 out.folded2 | ./FlameGraph/flamegraph.pl > diff2.svg

    DEMO:

    //test.c#include #include void foo3(){  }void foo2(){    int i;    for(i=0 ; i < 10; i++)      foo3();}void foo1(){    int i;    for(i = 0; i< 1000; i++)       foo3();}int main(void){    int i;  for( i =0; i< 1000000000; i++) {      foo1();      foo2();    }}//test1.c#include #include void foo3(){}void foo2(){  int i;  for(i=0 ; i < 10; i++)         foo3();}void foo1(){    int i;    for(i = 0; i< 1000; i++)         foo3();}void add(){    int i;    for(i = 0; i< 10000; i++)       foo3();}int main(void){    int i;    for( i =0; i< 1000000000; i++) {    foo1();    foo2();    add();  }}

    DEMO红蓝差分火焰图:

    dabf2db05624acdb9b4f680882d59ef4.png

    10. 案例分析

    10.1 接入层nginx集群异常现象

    通过监控插件发现在 2017.09.25 19 点nginx集群请求流量出现大量的499,5xx状态码。并且发现机器cpu使用率升高,目前一直持续中。

    10.2 分析nginx相关指标

    a) **分析nginx请求流量:

    61946f8f27e5452a78dcb24726c9d5c7.png

    结论:

    通过上图发现流量并没有突增,反而下降了,跟请求流量突增没关系。

    b) **分析nginx响应时间2cc76a96aafa4d4b2a208da4d5b0890d.png

    结论:

    通过上图发现nginx的响应时间有增加可能跟nginx自身有关系或者跟后端upstream响应时间有关系。

    c) **分析nginx upstream响应时间

    509e25b9fa90d5f09a9e95845f14baa3.png

    结论:

    通过上图发现nginx upstream 响应时间有增加,目前猜测可能后端upstream响应时间拖住nginx,导致nginx出现请求流量异常。

    10.3 分析系统cpu情况

    a) **通过top观察系统指标

    top

    c02dc81a1547f32a32e5e5e0a142225a.png

    结论:

    发现nginx worker cpu比较高

    b) **分析nginx进程内部cpu情况

    perf top -p pid

    结论:

    发现主要开销在free,malloc,json解析上面

    10.4 火焰图分析cpu
    a) **生成用户态cpu火焰图

    //on-CPU usersh ngx_on_cpu_u.sh pid//进入结果目录cd ngx_on_cpu_u//开一个临时端口8088python -m SimpleHTTPServer 8088//打开浏览器输入地址127.0.0.1:8088/pid.svg

    1404046fa27feced3fb3b4c0430a4516.png

    结论:

    发现代码里面有频繁的解析json操作,并且发现这个json库性能不高,占用cpu挺高。

    10.5 案例总结

    a) 分析请求流量异常,得出nginx upstream后端机器响应时间拉长

    b) 分析nginx进程cpu高,得出nginx内部模块代码有耗时的json解析以及内存分配回收操作

    10.5.1 深入分析

    根据以上两点问题分析的结论,我们进一步深入分析。

    后端upstream响应拉长,最多可能影响nginx的处理能力。但是不可能会影响nginx内部模块占用过多的cpu操作。并且当时占用cpu高的模块,是在请求的时候才会走的逻辑。不太可能是upstram后端拖住nginx,从而触发这个cpu的耗时操作。

    10.5.2 解决方式

    遇到这种问题,我们优先解决已知的,并且非常明确的问题。那就是cpu高的问题。解决方式先降级关闭占用cpu过高的模块,然后进行观察。经过降级关闭该模块cpu降下来了,并且nginx请求流量也正常了。之所以会影响upstream时间拉长,因为upstream后端的服务调用的接口可能是个环路再次走回到nginx。

    11.参考资料

    • http://www.brendangregg.com/index.html

    • http://www.brendangregg.com/FlameGraphs/cpuflamegraphs.html

    • http://www.brendangregg.com/FlameGraphs/memoryflamegraphs.html

    • http://www.brendangregg.com/FlameGraphs/offcpuflamegraphs.html

    • http://www.brendangregg.com/blog/2014-11-09/differential-flame-graphs.html

    • https://github.com/openresty/openresty-systemtap-toolkit

    • https://github.com/brendangregg/FlameGraph

    • https://www.slideshare.net/brendangregg/blazing-performance-with-flame-graphs
    作者:Lucien_168
    链接:https://www.jianshu.com/p/0bbac570fa4c
    展开全文
  • 这时候就需要登录服务器进一步深入分析问题的根源。那么分析问题需要有一定的技术经验积累,并且有些问题涉及到的领域非常广,才能定位到问题。所以,分析问题和踩坑是非常锻炼一个人的成长和提升自我能力。如果我们...
  • 继上周介绍了稳定性三大故障之一的ANR类故障后,本章继续介绍第二大类故障Crash/Tombstone及其分析定位方法。1. Crash/Tombstone问题原因分析2. Tombstone问题定位方法本节主要讲解Tombstone问题的分析定位方法。2.1...
  • 这时候就需要登录服务器进一步深入分析问题的根源。那么分析问题需要有一定的技术经验积累,并且有些问题涉及到的领域非常广,才能定位到问题。所以,分析问题和踩坑是非常锻炼一个人的成长和提升自我能力。如果我们...
  • 这时候就需要登录服务器进一步深入分析问题的根源。那么分析问题需要有一定的技术经验积累,并且有些问题涉及到的领域非常广,才能定位到问题。所以,分析问题和踩坑是非常锻炼一个人的成长和提升自我能力。如果我们...
  • 这时候就需要登录服务器进一步深入分析问题的根源。那么分析问题需要有一定的技术经验积累,并且有些问题涉及到的领域非常广,才能定位到问题。所以,分析问题和踩坑是非常锻炼一个人的成长和提升自我能力。如果我们...
  • 这时候就需要登录服务器进一步深入分析问题的根源。那么分析问题需要有一定的技术经验积累,并且有些问题涉及到的领域非常广,才能定位到问题。所以,分析问题和踩坑非常锻炼一个人的成长和提升自我能力。如果我们有...
  • 这时候就需要登录服务器进一步深入分析问题的根源。那么分析问题需要有一定的技术经验积累,并且有些问题涉及到的领域非常广,才能定位到问题。所以,分析问题和踩坑是非常锻炼一个人的成长和提升自我能力。如果我们...
  • Linux程序内存越界定位分析总结

    千次阅读 2020-01-30 14:23:54
    问题描述:最近在工作中遇到这样一个奇葩问题,程序里面需要使用到一个.so库,同一份源码用我的电脑编译出来的库放到程序...问题1:定位踩内存的地方 现象为触发某个业务条件,会导致程序其他业务运行不正常,异...
  • 本文主要分享一个Cache一致性踩内存问题的定位过程,涉及到的知识点包括:backtrace、内存分析、efence、wrap系统函数、硬件watchpoint、DMA、Cache一致性等。 1 背景 设备上跑的是嵌入式实时操作系统(RTOS,具体为...
  • 实际项目中发现Json-C用法不当导致的内存泄露、踩内存问题,大都是因为不清楚下面几个接口的用法。 以下分析基于https://github.com/json-c/json-c( 0.12.1 release)。 1. json_object_new_object生成的对象要...
  • 那么地址是从低位开始的,也就是如果我们对aa的操作越界了的话,那么可能会把a1和a2的值给覆盖掉,是从低往高处踩内存的。 void print(int b1,int b2) {  int a1=0,a2=1;  printf("a1
  • 2. 内存分配,推荐阅读Ptmalloc源码分析,无论是C还是C++程序员,这一部分是最容易雷的,多读一点基础的东西,会在解决实际问题的时候,不至于手足无措。以这些为基础,再结合Valgrind或Purify,相信效果会更好。...
  • 众所周知,从事linux内核开发的工程师或多或少都会遇到内核panic,亦或者是soft lockup,前者多半是因为内存泄露、内存、访问空地址等错误导致的,而后者可以肯定是因为代码的逻辑不当,进而导致内核进入一个死...
  • 警告背后的use after free

    千次阅读 2016-10-11 18:00:32
    用GAT解开db,并结合对应的vmlinux(该文件必须和db一致,具体请看FAQ06985),利用工具E-Consulter分析(也可以参考FAQ13941),分析里几个db发现都是内存踩坏,随机,这种情况要么是软件引入的,要么是硬件故障...
  • 我们常提到的"在Windows操作系统中安装VMware,运行Linux虚拟机"属于【C】。 A、 存储虚拟化 B、 内存虚拟化 C、 系统虚拟化 D、 网络虚拟化 下列传输介质中,哪种传输介质的抗干扰性最好? B (A)双绞线 (B)光缆...

空空如也

空空如也

1 2
收藏数 22
精华内容 8
关键字:

linux分析踩内存

linux 订阅