admin管理员组

文章数量:1544595

一、前言

Linux运维过程中,我们会遇到一些进程突然出现挂死的状态(即进程处于运行状态,但无法处理请求,比如会报404,但这时服务端口是通的,日志也没显示明显异常,有的会简单给出无法连接某个组件,比如数据库等),那这时我们如何定位排查问题呢,偶然间看到网上一位同学的文章,这里综合自己工作经验重新组织分享一下。

二、故障分析思路

遇到系统问题,有一个清晰的分析思路其实比直接解决问题本身更重要,分析思路又要围绕问题定位,重点就是快速缩小范围确定边界,采用最小适用法则和加减法+情景假设,快速定位问题,有条件的汇出路径图,鱼骨图等,解决问题后再复盘整个过程。结合相关经验,大体可从6个方面来分析:


注 : 常见指标含义说明

buffer(写缓冲):是用于存放(缓冲)要输出到disk(块设备)的数据的;
cache(读缓存):是缓存从disk上读出的数据。buffer和cache都是为了提高IO性能,并由OS来管理;
swap:linux内核读写虚拟内存是以 “页” 为单位操作的,把内存转移到硬盘交换空间(SWAP)和从交换空间读取到内存 的时候都是按页来读写的;
Paging:内存和SWAP的这种交换过程称为页面交换(Paging)



  • SMART(S=Specific、M=Measurable、A=Attainable可实现的、R=Relevant相关的、T=Time-bound时限)
  • 5W+1H(六何分析法):对象 (What)、场所/景 (Where)、时间和程序 (When)、相关人(Who)、原因(Why)、方式 (How)


1)系统负载和cpu:

这个是最直观的,数据也是最容易获取的,监控软件基本都满足,云平台也可一般都支持显示,通过查看历史数据,或查看当前linux OS的负载和CPU使用率,可首先看系统整体是否超载或当前cpu超载;

load average(平均负载:CPU性能指标):在特定时间间隔内运行队列中(在CPU上运行或者等待运行多少进程)的平均进程数。如果一个进程满足以下条件则其就会位于运行队列中:
  - 它没有在等待I/O操作的结果;
  - 它没有主动进入等待状态(也就是没有调用’wait’);
  - 没有被停止(例如:等待终止);
在Linux中,进程分为三种状态,一种是阻塞的进程blocked process,一种是可运行的进程runnable process,另外就是正在运行的进程running process。当进程阻塞时,进程会等待I/O设备的数据或者系统调用。
  进程可运行状态时,它处在一个运行队列run queue中,与其他可运行进程争夺CPU时间。 系统的load是指正在运行running one和准备好运行runnable one的进程的总数。比如现在系统有2个正在运行的进程,3个可运行进程,那么系统的load就是5。load average就是一定时间内的load数量。如果是单核CPU,1是理论的临界值,我们希望负载平均值小于 1.00,对于多核CPU,满负荷状态的数字为 “1.00 * CPU核数”,n核就小于n;单线程任务只会使用一个CPU,不管CPU核数有多少。

2)内存分析

同上,内存指标获取也相对容易,而且内存过载造成的卡死,系统也会假死掉,比如:系统登录执行命令卡慢,远程无法登录,云平台console登录界面卡死没有反应,内核崩溃出现告警等;

3)网络IO与流量:

同上,网络IO及带宽流量数据也获取相对容易,且通过流量趋势图,可判断是否存在网络IO问题,导致网络本身请求无法处理,如果出现网络IO,这时我们的ip一般也会ping不通,端口无法telnet,无法远程登录,网页404,趋势图流量异常增高,不在正常业务激增区间;甚至出现安全问题;

4)磁盘IO与空间使用

如果文件系统使用率占满,也会导致程序阻塞,无法接受响应处理请求,或磁盘直接与OS断联,通信故障,挂载故障,或大量小文件耗尽inode,或进程占用导致删除的文件空间无法释放,类似OOM一样,磁盘空间被累积堆满,导致其上程序阻塞;另外如果是磁盘IO问题,导致读写数据无法满足要求,或写入阻塞,或读延迟,导致系统超时报错等;另外也有可能是文件篡改,中毒等导致磁盘异常;

5)文件描述符fd占用

如4中所述,可能存在很多未被进程释放的文件,显示deleted状态,但占用fd不会释放已经分配到的空间,文件实际被未有效删除,释放空间,导致累积性磁盘使用耗尽问题

6)线程占用与运行

部分线程可能由于以上几种原因阻塞,导致争抢cpu无法释放,CPU显示%之3-400,进程虽然存活,端口也能telnet,但是线程处理某任务,处于阻塞状态,无法自行恢复,因当前可能就是正常的业务处理逻辑,所以并不会触发抛错机制;可分析进程背后线程阻塞的深层次原因定位,看是具体哪些任务/接口调用导致了相关问题;


另外,针对应用的分析,我们又可简单统称为应用系统级性能分析,通常包括两个阶段:性能剖析(performance profiling)和代码优化。

性能剖析:寻找应用性能瓶颈,查找引发性能问题的原因及热点代码。

代码优化:针对具体性能问题而优化代码或编译选项,以改善软件性能。


7)软件安装或命令运行错误:

  • 1、因库文件路径或真实不存在导致的报错找不到库文件或安装某软件,执行某命令失败报错,一般是路径问题,先确认该库文件*.so是否存在,存在就是路径问题,然后加库环境变量**;LIBRARY_PATH** 环境变量:用于指定程序静态链接库文件搜索路径,用 .a 为后缀,一般静态库的代码在编译过程中已经被载入可执行程序。LD_LIBRARY_PATH 环境变量:指定程序动态链接库文件搜索路径,又称共享库,一般用 .so 为后缀,常见库文件名后都会加上版本号一起作为后缀,例如:libpython3.9.so.1.0:;它的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用。库的搜索顺序如下:
  • 动态库链接时搜索路径的顺序:

    编译目标代码时指定的动态库搜索路径;
    环境变量 LD_LIBRARY_PATH 指定动态库搜索路径,它指定程序动态链接库文件搜索路径;
    配置文件 /etc/ld.so.conf 中指定的动态库搜索路径;
    默认的动态库搜索路径 /lib;
    默认的动态库搜索路径 /usr/lib。
    \
  • 静态库链接时搜索路径的顺序:

    ld 会去找 gcc / g++ 命令中的参数 -L ;
    再找 gcc 的环境变量 LIBRARY_PATH,它指定程序静态链接库文件搜索路径;
    再找默认库目录 /lib,/usr/lib,/usr/local/lib,这是当初 compile gcc 时写在程序内的。
    \
  • 2、可执行命令不存在,或安装包不存在,或yum源配置问题,或yum网络不通;或yum资源站不存在目标资源,请更换其他源;
    \
  • 3、软件或命令执行依赖的第三方程序未事先安装

三、分析工具


1)CPU查看命令

cat /proc/cpuinfo
grep ‘model name’ /proc/cpuinfo | wc -l //查看cpu总核心数命令或
grep -c ‘model name’ /proc/cpuinfo
cat /proc/cpuinfo | grep ‘physical id’ | sort | uniq | wc -l
cat /proc/cpuinfo | grep ‘cpu cores’ | sort | uniq #查看 CPU 物理核数
cat /proc/cpuinfo | grep ‘siblings’ | sort | uniq 查看 CPU 逻辑核数

CPU负载查看:经验法则是:平均负载 = 0.7 * CPU 逻辑核数,当平均负载持续大于 1.0 * CPU 逻辑核数,必须寻找解决办法,降低平均负载;当平均负载持续大于 5.0 * CPU 逻辑核数,表明系统已出现严重问题,长时间未响应,或者接近死机;当 load1 远大于 load5 或 load15 时,表明系统负载在急剧升高,如果不是临时性抖动,而是持续升高,特别是当 load5 都已超过 0.7 * CPU 逻辑核数 时,应调查原因;另2种场景:

CPU 密集型应用:大量进程在等待或使用 CPU,此时 CPU 使用率与平均负载呈正相关状态。
I/O 密集型应用:大量进程在等待 I/O,此时平均负载会升高,但 CPU 使用率不一定很高

经验:%iowait 表示在一个采样周期内有百分之几的时间属于以下情况:CPU空闲、并且有仍未完成的I/O请求。在CPU繁忙期间发生的I/O,无论有多少,%iowait 的值都是不受影响的(因为 %iowait 的第一个前提条件就是CPU必须空闲);当CPU繁忙程度下降时,有一部分I/O落入了CPU空闲的时间段内,也会导致 %iowait 升高。 %iowait 的高低与I/O的多少没有必然关系,而是与I/O的并发度相关;最后再结合读写等待和队列长度进行确认。

#对于单核CPU来说,可参考如下经验判定:

1分钟Load>1,5分钟Load<1,15分钟Load<1:短期内繁忙,中长期空闲,初步判断是一个“抖动”,或者是“拥塞前兆”
1分钟Load>1,5分钟Load>1,15分钟Load<1:短期内繁忙,中期内紧张,很可能是一个“拥塞的开始”
1分钟Load>1,5分钟Load>1,15分钟Load>1:短、中、长期都繁忙,系统“正在拥塞”
1分钟Load<1,5分钟Load>1,15分钟Load>1:短期内空闲,中、长期繁忙,不用紧张,系统“拥塞正在好转

1、top命令

shift + h 按线程查看cpu消耗情况,查看每个核消耗情况
us 过高说明应用程序消耗了大部分cpu,经验值参考:65%~70%
sy 过高表示系统线程切换频繁,经验值:30%~35%,高于此数值时,观察是否有过多的中断或上下文切换;
wa 表示为在执行过程中等待io所占的百分比 hi 硬件中断(ex:网卡接收数据频发)
top -p pid 多列信息列表中直显示对应进程信息.;大写P,结果按CPU占用降序排序



其中,状态D,表示 uninterruptible sleep,这种状态是不可中断的,无论是kill,kill -9,还是kill -15。处于D状态的进程通常是在等待IO,比如磁盘 IO,网络 IO,其他外设 IO。如果处于D状态的时间较长,意味着可能是IO设备本身出了故障,需要排查设备是否正常。

2、查看CPU占用最多的前10个进程
ps auxw | head -1;
ps auxw | sort -rn -k3 | head -10

3、uptime 查看 load average
00:13:49 up 117 days, 13:22, 2 users, load average: 0.00, 0.01, 0.05

4、htop查看: Load Average和Uptime和各个进程的耗用详情,内存

5、atop命令:
CPU列显示CPU整体(即多核CPU作为一个整体CPU资源)的使用情况,我们知道CPU可被用于执行进程、处理中断,也可处于空闲状态(空闲状态分两种,一种是活动进程等待磁盘IO导致CPU空闲,另一种是完全空闲);各个字段指示值相加结果为N00%,其中N为cpu核数。



sys、usr字段:指示CPU被用于处理进程时,进程在内核态、用户态所占CPU的时间比例
irq字段:指示CPU被用于处理中断的时间比例
idle字段:指示CPU处在完全空闲状态的时间比例
wait字段:指示CPU处在“进程等待磁盘IO导致CPU空闲”状态的时间比例
csw字段:指示上下文交换次数
intr字段:指示中断发生次数

6、dstat命令

dstat 2 10 //每2秒采集一次共采集10次,默认dstat每秒都会刷新数据,输出结果说明:
cpu列里:hiq、siq分别为硬中断和软中断次数;当CPU的状态处在"waits"时,那是因为它正在等待I/O设备(例如内存,磁盘或者网络)的响应而且还没有收到。
system列:int、csw分别为系统的中断次数(interrupt)和上下文切换次数(context switch);这项统计仅在有比较基线时才有意义。这一栏中较高的统计值通常表示大量的进程造成拥塞,需要对CPU进行关注。

dstat 是一个可以取代vmstat,iostat,netstat和ifstat这些命令的多功能产品。它增加了一些另外的功能,增加了监控项,也变得更灵活了,它还支持输出CSV格式报表,并能导入到Gnumeric和Excel以生成图形。dstat可以很方便监控系统运行状况并用于基准测试和排除故障。我们可实时地看到所有系统资源,例如:通过统计IDE控制器当前状态来比较磁盘利用率,或者直接通过网络带宽数值来比较磁盘的吞吐率(在相同的时间间隔内)。yum -y install dstat 即可安装。

常用参数:
-l :显示负载统计量
-m :显示内存使用率(包括used,buffer,cache,free值)
-r :显示I/O统计
-s :显示交换分区使用情况
-t :将当前时间显示在第一行
–fs :显示文件系统统计数据(包括文件总数量和inodes值)
–nocolor :不显示颜色(有时候有用)
–socket :显示网络统计数据
–tcp :显示常用的TCP统计
–udp :显示监听的UDP接口及其当前用量的一些动态数据
-c:表示只显示我们的CPU信息
-p:表示只显示我们的进程信息
-n:表示只显示我们的网络信息
-–disk-util :显示某一时间磁盘的忙碌状况
-–freespace :显示当前磁盘空间使用率
-–proc-count :显示正在运行的程序数量
-–top-bio :指出块I/O最大的进程
-–top-cpu :图形化显示CPU占用最大的进程
-–top-io :显示正常I/O最大的进程
-–top-mem :显示占用最多内存的进程

eg1: dstat 2 10
You did not select any stats, using -cdngy by default.
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw 
  2   0  98   0   0   0|  26k   39k|   0     0 |   0     0 |2222  3985 
  1   1  98   0   0   0|   0     0 |6458B   19k|   0     0 |3905  8052 
  2   1  97   0   0   0|   0     0 |  24k   21k|   0     0 |4397  8494 
  6   1  94   0   0   0|   0   116k|  22k   37k|   0     0 |5466  9090 
  1   1  98   0   0   0|   0     0 |7846B   19k|   0     0 |3777  7509 
  1   1  98   0   0   0|   0    76k|6141B   17k|   0     0 |3802  7597 
  1   1  99   0   0   0|   0     0 |2350B   10k|   0     0 |4071  7912 
  2   1  98   0   0   0|   0     0 |  23k   19k|   0     0 |4274  8029 
  1   1  98   0   0   0|   0   116k|  25k   40k|   0     0 |4314  8235 
  1   1  98   0   0   0|   0     0 |  15k   21k|   0     0 |3820  7635 
  1   1  98   0   0   0|   0   182k|9072B   20k|   0     0 |4550  8393 

eg2:dstat -c -y -l --proc-count --top-cpu  //显示CPU资源损耗

eg3:dstat -g -l -m -s --top-mem //查看全部内存占用

eg4:dstat –output /tmp/sampleoutput.csv -cdn  //输出一个csv格式的文件

7、perf 工具

Perf Event 是一款随 Linux 内核代码一同发布和维护的性能诊断工具,由内核社区维护和发展。Perf 不仅可以用于应用程序的性能统计分析,也可用于内核代码的性能统计和分析。目前已经又越来越多的新功能被加入 Perf,使其已经成为一个多功能的性能统计工具集 。Perf 可收集 Linux 中各种性能数据,帮助我们排查分析软件性能问题。该工具包包含了:perf-stat (perf stat), perf-top (perf top), perf-record (perf record), perf-list (perf list);perf 是 Linux 2.6.31 以后内置的性能分析工具,没有的话 yum install perf -y安装。它以性能事件采样为基础,不仅可以分析系统的各种事件和内核性能,还可以用来分析指定应用程序的性能问题。使用 perf 分析 CPU 性能非常好用。常见用法是 perf top,类似于 top,它能够实时显示占用 CPU 时钟最多的函数或者指令,可以用来查找热点函数;perf top 虽然实时展示了系统的性能信息,但它的缺点是并不保存数据,也就无法用于离线或者后续的分析。这时我们可使用perf record ,它提供了保存数据的功能,保存后的数据,可以用 perf report 解析展示。实际使用中,我们还经常为 perf top 和 perf record 加上 -g 参数,开启调用关系的采样,方便我们根据调用链来分析性能问题,注意采样数据过少的话数据会不准确。另外需要对内核比较了解,才有利于正确分析相关调用。

通过Perf工具集,应用程序可利用 PMU,tracepoint 和内核中的特殊计数器来进行性能统计;不但可以分析指定应用程序的性能问题 (per thread),也可以用来分析内核的性能问题,当然也可以同时分析应用代码和内核,从而全面理解应用程序中的性能瓶颈。最初,它叫做 Performance counter,在 2.6.31 中第一次亮相。在 2.6.32 中它正式改名为 Performance Event,因为 perf 已不再仅仅作为 PMU (performance monitor unit性能管理单元)的抽象,而是能够处理所有的性能相关的事件

Perf可以分析程序运行期间发生的硬件事件,比如 instructions retired ,processor clock cycles 等;也可以分析软件事件,比如 Page Fault 和进程切换。eg:使用 Perf 可以计算每个时钟周期内的指令数,称为 IPC,IPC 偏低表明代码没有很好地利用 CPU。Perf 还可以对程序进行函数级别的采样,从而了解程序的性能瓶颈究竟在哪里等等。Perf 还可以替代 strace,可以添加动态内核 probe 点,还可以做 benchmark 衡量调度器的好坏。

eg1: perf top -e xxx  //-e后跟perf list里列出来的事件类型,实时查看当前系统进程函数占用率情况

eg2:perf top -e cpu-clock  //查看CPU的使用

eg3:perf top -e faults //查看 page faults

eg4:perf top -e block:block_rq_issue //查看系统IO的请求,比如可以在发现系统IO异常时,可以使用该命令进行调查,就能指定到底是什么原因导致的IO异常。 block_rq_issue 表示 block_request_issue 就是IO请求数。

eg5:perf top -g -p 1234 //实时查看进程1234CPU耗用,-g:可以查看堆栈调用;-a:查看所有CPU

eg6:perf record -ag -- sleep 15 perf report //查看CPU事件占比,调用栈,CPU使用情况
#其他

eg7:perf list //列出所有能够触发 perf 采样点的事件,一般可分为三类:

//Hardware Event 是由 PMU 硬件产生的事件,比如 cache 命中,当需要了解程序对硬件特性的使用情况
时,便需要对这些事件进行采样;

//Software Event 是内核软件产生的事件,比如进程切换,tick 数等 ;

//Tracepoint event 是内核中的静态 tracepoint 所触发的事件,这些 tracepoint 用来判断程序运行期间内核的行为细节,比如 slab 分配器的分配次数等。

eg8:perf stat 可执行程序  //提供被调试程序运行的整体情况和汇总数据,这也是我们经查分析应用问题时使用该工具的第一步,检查你的应用时 CPU bound 型还是IO或内存密集型;使用 -e 选项还可查看你指定的事件;输出结果说明:

//Task-clock-msecs:CPU 利用率,该值高,说明程序的多数时间花费在 CPU 计算上而非 IO。

//Context-switches:进程切换次数,记录了程序运行过程中发生了多少次进程切换,频繁的进程切换是应该避免的。

//Cache-misses:程序运行过程中总体的 cache 利用情况,如果该值过高,说明程序的 cache 利用不好

//IPC:是 Instructions/Cycles 的比值,该值越大越好,说明程序充分利用了处理器的特性。

//Cache-references: cache 命中的次数

//Cache-misses: cache 失效的次数

//使用perf stat 时,一般是已经有一个调优的目标,但当不确定时,可用perf top列出所有值得怀疑的进程;
//perf top 用于实时显示当前系统的性能统计信息。主要用来观察整个系统当前的状态,比如:可以通过查看该
//命令的输出来查看当前系统最耗时的内核函数或某个用户进程;同样使用-e 选项,您以列出造成其他事件的 TopN 个进程 / 函数。比如:

eg9:pert top -e cache-miss   //看谁造成的 cache miss 最多

//对于粒度更细的信息,可用 perf record 记录单个函数级别的统计信息,并使用 perf report 来显示统计结果来分析

eg10:perf record -e cpu-clock 应用  //查看占用cpu多的代码片段/函数
perf report

eg11:perf record -e cpu-clock -g 应用  //通过g参数来查看函数调用关系并显示统计信息
perf report

eg12:perf stat -e task-clock,context-switches,cpu-migrations,page-faults,cycles,stalled-cycles-frontend,stalled-cycles-backend,instructions,branches,branch-misses,L1-dcache-loads,L1-dcache-load-misses,LLC-loads,LLC-load-misses,dTLB-loads,dTLB-load-misses ls

8、ps命令
eg1:ps aux --sort=-%cpu //按CPU使用率排序,找出CPU消耗最多进程
eg2:ps auxw | head -1;ps auxw | sort -rn -k3 | head -10 //CPU占用最多的前10个进程

9、mpstat命令
mpstat是 Multiprocessor Statistics的缩写,是实时系统监控工具。其报告与CPU的一些统计信息,这些信息存放在/proc/stat文件中。在多CPU系统里,其不但能查看所有CPU的平均状况信息,而且能够查看特定CPU的信息。yum -y install sysstat安装即可。mpstat 可以显示每个处理器的统计,而 vmstat 显示所有处理器的统计。场景:比如一个程序运行在一个多处理器机器上,但可能出现不使用所有处理器的情况,从而导致一个 CPU 过载,而其他 CPU 却很空闲。通过 mpstat 可以轻松诊断这些类型的问题。
eg1:mpstat //当mpstat不带参数时,输出为从系统启动以来的平均值
eg2:mpstat -P ALL 1 //查看单核CPU是否被打爆
eg3:mpstat -P ALL 5 2 //每5秒刷新一次,刷新2次
eg4: mpstat -P n //显示第n个cup信息,n为数字,计数从0开始

结果说明:
%iowait:在internal时间段里,硬盘IO等待时间(%),iowait/total100;
%irq:在internal时间段里,硬中断时间(%)=irq/total
100;
%steal:显示虚拟机管理器在服务另一个虚拟处理器时虚拟CPU处在非自愿等待下花费时间的百分比
%idle:在internal时间段里,CPU除去等待磁盘IO操作外的因为任何原因而空闲的时间闲置时间(%)
total_cur = user + system + nice + idle + iowait + irq + softirq
total_pre = pre_user + pre_system + pre_nice + pre_idle + pre_iowait + pre_irq + pre_softirq
user = user_cur – user_pre
total = total_cur - total_pre //其中_cur 表示当前值,_pre表示interval时间前的值。

10、sar命令
sar命令也包含在sysstat软件包内。
sar -u 3 5 //查看CPU负载
sar -u ALL 1 //获取所有CPU的 %user、%nice、%system、%iowait、%steal 和 %idle 指标,每1秒采样一次。

11、其他

watch -n 3 ‘cat /proc/loadavg’ //每隔3秒查看机器负载
cat /proc/cpuinfo |grep “processor”|sort -u|wc -l //看逻辑CPU个数
grep “physical id” /proc/cpuinfo|sort -u|wc -l //查看物理CPU个数
grep “cpu cores” /proc/cpuinfo|uniq //查看每个物理CPU内核个数
grep “siblings” /proc/cpuinfo|uniq //个物理CPU上逻辑CPU个数
cat /proc/cpuinfo //flags是否存在ht,存在即支持超线程
java工具:快速查看占用CPU前五的java线程栈:https://github/iqiancheng/fast-profiler
https://github/luckman666/show-busy-java-threads

案例1: CPU使用率高,IO无作业,Load Average低,系统反应颠簸

这种场景,通常是计算密集型任务,即大量生成耗时短的计算任务。这种任务会占满CPU资源,造成系统响应速度颠簸,但由于每个任务能快速计算完成,不会在运行队列堆积,所以在Load Average里不会体现出来。

案例2: CPU使用率低,IO等待,Load Average高,系统不卡

如下图模拟场景:
dd if=/dev/zero of=testx.img bs=512count=1000000 oflag=dsync //
这种场景,通常是IO密集型任务,如果大量请求都集中于相同的IO设备,超出设备的响应能力,会造成任务在运行队列里堆积等待,也就是D状态进程堆积,那么此时Load Average就会飙高。由于任务都处于等待状态,所以Load Average的值虽然很高,但系统响应速度不受影响。

案例3: CPU使用率低,IO繁忙,Load Average低,系统卡

这种场景,通常是低频大文件读写,由于请求数量不大,所以任务都处于R状态,Load Average数值反映了当前运行的任务数,不会飙升,IO设备处于满负荷工作状态,导致系统响应能力降低。模拟命令:
少量写大文件:dd if=/dev/zero of=testx.img bs=5120000count=10000 oflag=dsync //可看到dd程序都处于R状态

案例4: CPU使用率高,IO繁忙/等待,Load Average高,系统卡

这种场景,通常是服务混部,即IO、计算密集型任务混部在一起,相当于CPU、IO都处于高负荷状态,那么Load Average 自然很高。

12、CPU上下文切换

一个标准的Linux内核可以支持运行50~50000个进程运行,对于普通的CPU,内核会调度和执行这些进程。每个进程都会分到CPU的时间片来运行,当一个进程用完时间片或者被更高优先级的进程抢占后,它的相关状态数据会备份到CPU的运行队列中,同时其他进程在CPU上运行。这个进程切换的过程被称作上下文切换。>

Linux系统具有两个不同级别的运行模::内核态和用户态,其中内核态的运行级别要大于用户态,这个级别可以进行任何操作,一般内核运行与内核态,而应用程序是运行在用户态。当发生上下文切换时,通过系统调用,处于用户态的应用程序就会进入内核空间,待调用完成之后重新返回值到用户态运行,因此上下文切换存在系统开销,会一定程度上增加%sys的值。

当一个进程在执行时,所占CPU的所有寄存器中的值、进程的状态以及堆栈中的内容被称为该进程的上下文。当内核需要切换到另一个进程时,它需要保存当前进程的所有状态,即保存当前进程的上下文,以便恢复后再次执行该进程时,能够恢复到切换时的状态继续执行下去。在LINUX中,当前进程上下文均保存在进程的任务数据结构中。在发生中断时,内核就在被中断进程的上下文中,在内核态下执行中断服务进程,但同时会保留所有需要用到的资源,以便中断服务结束时能恢复被中断进程的执行。

那引起上下文切换的原因有哪些? 对于抢占式操作系统而言, 大体有几种:

  • 当前任务的时间片用完之后,系统CPU正常调度下一个任务;
  • 当前任务碰到IO阻塞,调度线程将挂起此任务,继续下一个任务;
  • 多个任务抢占锁资源,当前任务没有抢到,被调度器挂起,继续下一个任务;
  • 用户代码挂起当前任务,让出CPU时间;
  • 软/硬件中断; 中断是指CPU执行程序时,由于发生了某种随机的事件(外部或内部),引起CPU暂时中断正在运行的程序,转去执行一段特殊的服务程序(称为中断服务程序或中断处理程序),以处理该事件,该事件处理完后又返回被中断的程序继续执行。其中,软中断又称内部中断,由软件系统本身发给操作系统内核的中断信号,通常是由硬中断处理程序或进程调度程序对操作系统内核的中断,也就是我们常说的系统调用(System Call)。一般情况下软中断是处理I/O请求时发生订单,这些请求会调用内核中的处理I/O的程序,对于某些设备,I/O请求需要被立即处理,而磁盘I/O请求通常可以排队并且可以稍后处理。根据I/O模型的不同,进程或许会被挂起直到I/O完成,此时内核调度器就会选择另一个进程去运行。I/O可以在进程之间产生并且调度过程通常和磁盘I/O的方式是相同。在I/O密集型系统中可能会出现大量的中断请求,中断会产生中断上下文,造成CPU开。引入中断的原因有以下几点:
  • 提高数据传输率;
  • 避免了CPU不断检测外设状态的过程,提高了CPU的利用率。
  • 实现对特殊事件的实时响应。如多任务系统操作系统中缺页中断、设备中断、各类异常、实时钟等
#vmstat 2 3
#si: 从磁盘交换到内存的内存量(单位通常是KB/秒),so: 从内存交换到磁盘的内存量(单位通常是KB/秒);b: 等待资源的进程数,通常是等待I/O操作完成的进程;st: 被偷取的时间百分比,这通常发生在虚拟化环境中,表示虚拟CPU等待物理CPU的时间
#其中:in每秒中断次数,中断数量,cs为每秒上下文切换次数;

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 329428 414720 9934944    0    0     6    20    0    0  0  1 99  0  0
# mpstat中的 %irq %soft分别为硬中断和软中断所占CPU时间片比例
# mpstat 2 3
Linux 5.10.0-60.70.0.94.oe2203.bclinux.x86_64 (HBYG-Portal) 	06/12/2024 	_x86_64_	(8 CPU)

09:26:18 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
09:26:20 AM  all    0.13    0.00    0.06    0.00    0.50    0.06    0.00    0.00    0.00   99.25
09:26:22 AM  all    0.25    0.00    0.38    0.00    0.44    0.00    0.00    0.00    0.00   98.94
09:26:24 AM  all    1.06    0.00    0.81    0.00    0.44    0.00    0.06    0.00    0.00   97.62
Average:     all    0.48    0.00    0.42    0.00    0.46    0.02    0.02    0.00    0.00   98.60

2)内存查看定位

1、top/htop/atop命令

VIRT:进程占用的虚拟内存
RES:进程占用的物理内存
SHR:进程使用的共享内存
大写M,结果按内存占用降序排序
2、free -m

total:表示物理,内存总量
used:总计分配给缓存(包含Buffer和cache)使用的数量,但其中可能部分缓存并未实际使用
free:未被分配的内存。是真正尚未被使用的物理内存数量。
shared:共享内存,一般系统不会用到,这里也不讨论
buff:系统分配但未被使用的buffers数量
cache:系统分配但未被使用的cache数量
(cache是cpu和内存之间的,buffer是内存和磁盘之间的,都是为了解决速度不对等的问题。
缓存(cache)是把读取过来的数据保存起来,重新读取时若命中,就不去硬盘了,若没有命中就去读硬盘,其中的数据会根据读取频率进行组织,把最频繁读取的内容放在最容易找到的位置,把不再读取的内容不断往后排,直至从中删除。
缓冲(buffer)时根据磁盘的读写设计的,把分散的写操作集中进行,减少磁盘碎片和硬盘的的反复寻道,从而提高系统性能,linux有一个守护进程定期清空缓冲内容(即写入磁盘)。
buffer是即将要写入磁盘的,而cache是被从磁盘中读出来的。)
available:和free是有区别的,是实际可以用的最大空间。是应用程序认为可用内存数量,available = free + buff/cache (注:只是大概的计算方法)Linux 为了提升读写性能,会消耗一部分内存资源缓存磁盘数据,对于内核来说,buffer 和 cache 其实都属于已经被使用的内存。但当应用程序申请内存时,如果 free 内存不够,内核就会回收 buffer 和 cache 的内存来满足应用程序的请求。这就是稍后要说明的 buffer 和 cache。

3、vmstat命令(Virtual Meomory Statistics(虚拟内存统计))

vmstat 工具提供了一种低开销的系统性能观察方式。它可对系统的整体情况进行统计,不足之处是无法对单个进程进行深入分析。虚拟内存是利用磁盘空间虚拟出的一块逻辑内存,用作虚拟内存的磁盘空间被称为交换空间(Swap Space)。linux的内存管理采取的是分页存取机制,为了保证物理内存能得到充分的利用,内核会在适当的时候将物理内存中不经常使用的数据块自动交换到虚拟内存中,而将经常使用的信息保留到物理内存。不是所有页面在不用时都交换到虚拟内存,linux内核根据”最近最经常使用“算法,仅仅将一些不经常使用的页面文件交换到虚拟内存,有时我们会看到这么一个现象:linux物理内存还有很多,但是交换空间也使用了很多。例如,一个占用很大内存的进程运行时,需要耗费很多内存资源,此时就会有一些不常用页面文件被交换到虚拟内存中,当随后这个占用很多内存资源的进程结束并释放了内存时,刚才被交换出去的页面文件并不会自动的交换进物理内存一起释放,从而我们可看到此时虚拟内存还是占用,物理内存很少;交换空间里的页面在使用时会首先被交换到物理内存,如果此时没有足够的物理内存来容纳这些页面,它们又会被马上交换出去,当虚拟内存中可能没有足够空间来存储这些交换页面,可能就会导致linux出现假死机、服务异常等问题;

常用参数
-a:显示活跃和非活跃内存
-f:显示从系统启动至今的fork数量 。
-m:显示slabinfo
-n:只在开始时显示一次各字段名称。
-s:显示内存相关统计信息及多种系统活动数量。
delay:刷新时间间隔。如果不指定,只显示一条结果。
count:刷新次数。如果不指定刷新次数,但指定了刷新时间间隔,这时刷新次数为无穷。
-d:显示磁盘相关统计信息。
-p:显示指定磁盘分区统计信息
-S:使用指定单位显示。参数有 k 、K 、m 、M ,分别代表1000、1024、1000000、1048576字节(byte)。默认单位为K(1024 bytes)
-V:显示vmstat版本信息。

eg1:vmstat 2 //查看内存使用情况,内存状态
eg2:vmstat -a 2 5 //显示活跃和非活跃内存,inact: 非活跃内存大小,active: 活跃的内存大小
eg3:vmstat -f //查看系统已经fork了多少次,该数据实际是从/proc/stat中的processes字段里读取的
eg4:vmstat -m //查看系统的slab信息,读取/proc/slabinfo,等同cat /proc/slabinfo;由于内核会有许多小对象,这些对象构造销毁十分频繁,比如i-node,dentry,这些对象如果每次构建的时候就向内存要一个页(4kb),而其实只有几个字节,这样就会非常浪费,为了解决这个问题,就引入了一种新的机制来处理在同一个页框中如何分配小存储区,slab可对这些小对象进行缓冲,可以重复利用,减少内存分配次数,这样就不用为每一个对象分配页框,从而节省了空间;



输出结果说明:
Memory(内存):
swpd: 使用虚拟内存大小
free: 可用内存大小
buff: 用作缓冲的内存大小,通常是给块设备I/O操作的缓存(单位通常是KB)。
cache: 用作缓存的内存大小,用于存储文件系统的数据和目录信息(单位通常是KB)
Swap:
si: 每秒从交换区写到内存的大小
so: 每秒写入交换区的内存大小
IO:(现在的Linux版本块的大小为1024bytes)
bi: 每秒读取的块数
bo: 每秒写入的块数

4、ps 命令
eg1:ps -eo pid,comm,rss | awk ‘{m=$3/1e6;s[“*”]+=m;s[$2]+=m} END{for (n in s) printf"%10.3f GB %s\n",s[n],n}’ | sort -nr | head -20 //统计前20内存占用;
eg2:awk ‘NF>3{s[“"]+=s[$1]=$3$4/1e6} END{for (n in s) printf”%10.1f MB %s\n",s[n],n}’ /proc/slabinfo | sort -nr | head -20 //统计内核前20slab的占用;slab是动态内存管理的一个算法机制,
eg3:ps auxw | head -1;ps auxw|sort -rn -k4 | head -10 //内存消耗最多的前10个进程
eg4:ps auxw | head -1;ps auxw | sort -rn -k5 | head -10 //虚拟内存使用最多的前10个进程
eg5:ps auxw –sort=rss //VSZ 进程所使用的虚存的大小;RSS 进程使用的驻留集大小或者是实际内存的大小(RSS is the “resident set size” meaning physical memory used)

部分词汇说明:

1>虚拟内存原理:

在系统中运行的每个进程都需要使用到内存,但不是每个进程都需要每时每刻使用系统分配的内存空间。当系统运行所需内存超过实际的物理内存,内核会释放某些进程所占用但未使用的部分或所有物理内存,将这部分资料存储在磁盘上直到进程下一次调用,并将释放出的内存提供给有需要的进程使用。

在Linux内存管理中,主要是通过“调页Paging”和“交换Swapping”来完成上述的内存调度。调页算法是将内存中最近不常使用的页面换到磁盘上,把活动页面保留在内存中供进程使用。交换技术是将整个进程,而不是部分页面,全部交换到磁盘上。

分页(Page)写入磁盘的过程被称作Page-Out,分页(Page)从磁盘重新回到内存的过程被称作Page-In。当内核需要一个分页时,但发现此分页不在物理内存中(因为已经被Page-Out了),此时就发生了分页错误(Page Fault)

当系统内核发现可运行内存变少时,就会通过Page-Out来释放一部分物理内存。尽管Page-Out不是经常发生,但是如果Page-out频繁不断的发生,当内核管理分页的时间超过运行程式的时间时,系统效能会急剧下降。这时的系统已经运行非常慢或进入暂停状态,这种状态亦被称作thrashing(颠簸)

3)网络负载分析

1、netstat命令

eg1:netstat -nat|awk ‘{print awk $NF}’|sort|uniq -c|sort -n //查看连接状态分布
eg2:netstat -s //查看协议栈情况

2、其他
ethtool -S eth0 //查看网卡硬件情况
cat /proc/net/softnet_stat/ifconfig eth1 //查看网卡驱动情况

4)存储(IO)分析

1、IO分析

iostat -x sdc sdd sde1 sdb1 2 6 #查看以上磁盘的IO,-x: 显示详细磁盘 I/O 统计信息,每隔2s输出6次,只能估算总体IO,缺点在于,并不能知道具体是哪些进程在进行磁盘读写

输出结果需要关注: IOPS(包括 r/s 和 w/s)、响应时间(从发出 I/O 请求到收到响应的间隔时间延迟)以及吞吐量(指每秒的 I/O 请求大小,B/s);%util表磁盘忙处理 I/O 请求的百分比。过高的使用率(比如超过 60%)通常意味着磁盘 I/O 存在性能瓶颈;

>
IO问题分析流程:

Linux 3.10.0-1160.25.1.el7.x86_64 (zq-sihua-cms-backup) 	06/11/2024 	_x86_64_	(32 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          47.67    0.00    4.87    0.73    0.15   46.58

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sdd               0.66    17.67  915.96   22.54 12503.54  2343.70    31.64     0.35    0.38    1.04   24.40   0.21  19.53
sde1              0.09    22.51   22.39   40.35  5022.69 15437.93   652.29     0.56    8.97   14.39    5.97   1.27   7.94
sdb1              0.07    27.14   17.43   31.82  4357.55 11137.54   629.17     1.09   22.20   23.04   21.74   3.18  15.65
sdc               0.01     1.56    0.01    5.25     0.11    63.49    24.21     0.01    1.28    1.55    1.28   1.02   0.53

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          86.15    0.00    8.94    0.11    0.40    4.41

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sdd               0.00     0.00   16.00    0.00    64.00     0.00     8.00     0.02    1.25    1.25    0.00   1.25   2.00
sde1              0.00     0.00   99.50    5.00 39206.00  1788.00   784.57     0.49    4.74    4.64    6.60   1.36  14.20
sdb1              0.00    59.50  101.50   21.50 31804.00  9102.00   665.14     2.44   19.76    9.13   69.95   2.61  32.15
sdc               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          88.14    0.00    7.18    0.16    0.14    4.38

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sdd               0.00    25.00  255.50    1.00  1456.00   104.00    12.16     0.26    1.03    1.02    2.50   0.53  13.60
sde1             28.50    63.00   16.50  153.00  3116.00 71888.00   885.00    30.87  182.12    8.21  200.87   1.98  33.55
sdb1              0.00     0.00   19.00    0.00  5936.00     0.00   624.84     0.15    8.66    8.66    0.00   2.55   4.85
sdc               0.00     0.00    0.00    0.50     0.00     2.00     8.00     0.00    1.00    0.00    1.00   1.00   0.05

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          90.93    0.00    6.54    0.08    0.17    2.27

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sdd               0.00     0.00  221.50    0.00  1334.00     0.00    12.05     0.32    1.45    1.45    0.00   0.75  16.60
sde1              0.00     0.00   25.50    6.50   102.00  2406.00   156.75     0.08    2.42    1.59    5.69   0.75   2.40
sdb1              0.00    65.00    2.00   24.50     8.00 10038.00   758.19     2.23   84.26    8.75   90.43   4.81  12.75
sdc               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          86.71    0.00    8.76    3.29    0.36    0.88

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz     f/s f_await  aqu-sz  %util
sda              0.00      0.00     0.00   0.00    0.00     0.00    0.40      4.80     0.80  66.67    1.50    12.00    0.00      0.00     0.00   0.00    0.00     0.00    0.40    0.50    0.00   0.10
sdc              0.00      0.00     0.00   0.00    0.00     0.00   12.40    134.40     4.20  25.30    1.48    10.84    0.00      0.00     0.00   0.00    0.00     0.00    7.00    0.23    0.02   2.38
sdd           17115.60  86539.20    70.60   0.41    1.54     5.06  122.20  33576.80    21.00  14.66   11.53   274.77    0.00      0.00     0.00   0.00    0.00     0.00    0.80    1.50   27.79  99.36
sde              3.80     88.00    18.20  82.73    1.37    23.16    5.20   1473.60     4.40  45.83    5.31   283.38    0.00      0.00     0.00   0.00    0.00     0.00    0.40    1.00    0.03   1.34

结论说明:平均读写时间(avgrq-sz:平均每次设备I/O操作的数据大小)也比较短,说明磁盘的响应速度比较快;磁盘使用率(%util)为13.60%,表示该磁盘的利用率相对较低,可以继续承受更高的负载。rrqm/s:每秒合并的读操作次数;wrqm/s:每秒合并的写操作次数,即wmerege/s;r/s:每秒完成的读I/O设备次数;w/s:每秒完成的写I/O设备次数;avgqu-sz:平均I/O队列长度;svctm:平均每次I/O设备的操作服务时间;util%:一秒中有多少%的时间用于IO操作;如果await远大于svctm,说明I/O队列太长,得到的响应时间变慢,avgqu-sz值过大,也说明,I/O队列过长,可能存在硬盘瓶颈;另外:tps: 每秒传输的 I/O 请求次数;kB_read/s 和 kB_wrtn/s: 每秒读取和写入的数据量。kB_read 和 kB_wrtn: 读取和写入的总数据量。

注: iostat输出结果大多数是一段时间内的平均值,因此只能对系统整体情况进行分析,难以反应峰值情况,不能针对某个进程进行深入分析。另cpu部分:%steal:是衡量虚拟机CPU的指标,是指分配给本虚拟机的时间片被同一宿主机的其他的虚拟机使用,一般%steal值较高时,说明宿主机的资源使用已到达瓶颈;吞吐量=rkb/s+wkb/s;IOPS=r/s+w/s即每秒钟处理的I/O个数,IOPS是随机读写性能的关键衡量指标;响应时间=r_await+w_await;

2、IO性能测试

fio:性能测试工具,主要来测试磁盘的 IOPS、吞吐量以及响应时间等核心指标
格式:fio [options] [jobfile | options]

//IO测试验证,输出结果关注:
#slat ,是指从 I/O 提交到实际执行 I/O 的时长(Submission latency);
##clat ,是指从 I/O 提交到 I/O 完成的时长(Completion latency);
#lat ,指的是从 fio 创建 I/O 到 I/O 完成的总时长。
#bw ,代表吞吐量.
#iops ,其实就是每秒 I/O 的次数

# 随机读:direct=1跳过系统缓存,iodepth,表示使用异步 I/O(asynchronous I/O,简称 AIO)时,同时发出的 I/O 请求上限;rw=andread/randwrite 则分别表示随机读 / 写;ioengine,表示 I/O 引擎,它支持同步(sync)、异步(libaio)、内存映射(mmap)、网络(net)等各种 I/O 引擎,这里使用一步IO测试;bs,表示 I/O 的大小;
fio -name=randread -direct=1 -iodepth=64 -rw=randread -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb

# 随机写
fio -name=randwrite -direct=1 -iodepth=64 -rw=randwrite -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb

# 顺序读
fio -name=read -direct=1 -iodepth=64 -rw=read -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb

# 顺序写
fio -name=write -direct=1 -iodepth=64 -rw=write -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/sdb 

3、查看具体进程IO

top -b -n 1 | grep ‘D’ #告诉 top 命令以批处理模式运行,只运行一次
ps aux | awk ‘{print $2,$3,$8,$11}’ | sort -k 8| uniq -c | sort -nr | grep ‘D’
pidstat -d 1 3 #-d,统计io情况
pidstat -d -r #-d 参数表示显示 I/O 统计,-r 参数表示显示读取和写入的字节数

5)文件系统分析

6)进程、线程分析

1、htop命令/工具

htop 是Linux系统中的一个互动的进程查看器,一个文本模式的应用程序(在控制台或者X终端中),需要ncurses。与Linux传统的top相比,htop更加人性化。它可让用户交互式操作,支持颜色主题显示,可横向或纵向滚动浏览进程列表,并支持鼠标操作。安装只需要sudo apt install htop;

htop相比较top的优势:

可以横向或纵向滚动浏览进程列表,以便看到所有的进程和完整的命令行。
在启动上比top 更快。
杀进程时不需要输入进程号。
htop 支持鼠标选中操作(反应不太快)。
top 已不再维护。

参数:
-C --no-color        使用一个单色的配色方案
-d --delay=DELAY     设置延迟更新时间,单位秒
-h --help          显示htop 命令帮助信息
-u --user=USERNAME   只显示一个给定的用户的过程
-p --pid=PID,PID…    只显示给定的PIDs
-s --sort-key COLUMN  依此列来排序
-v –version        显示版本信息



使用说明:
每一个CPU的总用量情况,注意这条上面会有不同的颜色:

蓝色:显示低优先级(low priority)进程使用的CPU百分比。
绿色:显示用于普通用户(user)拥有的进程的CPU百分比。
红色:显示系统进程(kernel threads)使用的CPU百分比。
橙色:显示IRQ时间使用的CPU百分比。
洋红色(Magenta):显示Soft IRQ时间消耗的CPU百分比。
灰色:显示IO等待时间消耗的CPU百分比。
青色:显示窃取时间(Steal time)消耗的CPU百分比。

快捷键:
u – 用于显示特定用户拥有的所有进程。
P –用于基于高CPU消耗对进程进行排序。
M –用于基于高内存消耗对进程进行排序。
T –用于根据时间段对过程进行排序。
h –用于打开帮助窗口并查看此处未提及的更多快捷方式
上下键或PgUP, PgDn 选定想要的进程,左右键或Home, End 移动字段,当然也可以直接用鼠标选定进程;
Space 标记/取消标记一个进程。命令可以作用于多个进程,例如 “kill”,将应用于所有已标记的进程
U 取消标记所有进程
s 选择某一进程,按s:用strace追踪进程的系统调用
l 显示进程打开的文件: 如果安装了lsof,按此键可以显示进程所打开的文件
I 倒转排序顺序,如果排序是正序的,则反转成倒序的,反之亦然
+, - 在树视图模式下,展开或折叠子树。当子树折叠时,进程名称左侧会显示一个“+”号
a (在有多处理器的机器上) 设置 CPU affinity: 标记一个进程允许使用哪些CPU
u 显示特定用户进程
M 按Memory 使用排序
P 按CPU 使用排序
T 按time+ 使用排序
F 跟踪进程: 如果排序顺序引起选定的进程在列表上到处移动,让选定条跟随该进程。这对监视一个进程非常有用:通过这种方式,你可以让一个进程在屏幕上一直可见。使用方向键会停止该功能。
K 显示/隐藏内核线程
H 显示/隐藏用户线程
Ctrl-L 刷新
Numbers PID 查找: 输入PID,光标将移动到相应的进程上

2、atop命令

atop是一款用于监控Linux系统资源与进程的工具,它以一定的频率记录系统的运行状态,所采集的数据包含系统资源(CPU、内存、磁盘和网络)使用情况和进程运行情况,并能以日志文件的方式保存在磁盘中,服务器出现问题后,我们可获取相应的atop日志文件进行分析,其比较强大的地方是其支持我们分析数据时进行排序、视图切换、正则匹配等处理。

3、pidstat 命令

pidstat 命令也是 sysstat 工具的一个命令,用来监控全部或者指定进程的CPU、内存、线程、设备IO等系统资源的占用情况。pidstat 首次运行时显示自系统启动开始的各项统计信息,之后运行pidstat将显示自上次运行该命令之后的统计信息。用户可以通过指定统计的次数和时间来获得所需的统计信息。pidstat可以监控到进程级别的信息;意味着可以直接定位问题源头。

参数:
-u 默认的参数,显示各个进程的CPU使用统计
-r 显示各个进程的内存使用统计
-d 显示各个进程的IO使用情况
-p 指定进程号
-w 显示每个进程的上下文切换情况
-t 显示选择任务的线程的统计信息外的额外信息
-T { TASK | CHILD | ALL }
这个选项指定了pidstat监控的。TASK表示报告独立的task,CHILD关键字表示报告进程下所有线程统计信息。ALL表示报告独立的task和task下面的所有线程。
注意:task和子线程的全局的统计信息和pidstat选项无关。这些统计信息不会对应到当前的统计间隔,这些统计信息只有在子线程kill或者完成的时候才会被收集。
-V:版本号
-h:在一行上显示了所有活动,这样其他程序可以容易解析。
-I:在SMP环境,表示任务的CPU使用率/内核数量
-l:显示命令名和所有参数

eg1:pidstat 2 -p 进程号 //查看可疑进程CPU使用率变化情况;
eg2:pidstat -w -p 进程号 //查看可疑进程的上下文切换情况;
eg3:pidstat -d -p 进程号 //查看可疑进程的IO情况;
eg4:pidstat和pidstat -u -p ALL //2个命令是等效的,默认显示所有进程的CPU使用率
#以1秒为信息采集周期,分别获取cpu、内存和磁盘IO的统计信息
pidstat -u 1
pidstat -r 1
pidstat -d 1
eg5:pidstat -r 1 5 //查看活跃进程的内存使用情况,1s一次共5次
eg6:pidstat -U 1 5 //显示进程所属的用户名下的进程

4、lsof命令

lsof -p 进程号 //查看进程打开的文件;

5、strace命令

strace -f -T -tt -p 进程号 //显示进程发起的系统调用; #yum install strace集客
当我们执行某个命令,出现卡死或卡住的情况,不知道如何定位时,可使用strace+你要执行的命令,当出现类似:state ……,该处就是执行命令遇到异常的地方,比如nfs挂载的目标export异常,导致df -hT无法执行或对该挂载点的操作卡死等;

7)日志分析

8)内核问题

9)安全问题

10)平台关联问题

11)人为问题

四、附录:

1)常见架构

2)启动过程

BIOS加电自检—MBR引导—加载grub界面—加载liunx内核参数及文件系统—运行init进程—系统初始化—用户登录系统

BIOS的主要作用是检测连接硬件提供给操作系统和寻找启动(设备)硬盘并找到主引导记录MBR移交控制权。

MBR作为主引导记录负责加载grub并一起定位和加载 Linux 内核到内存中,grub转移控制权到内核。

内核启动后会向bios查询电脑的所有硬件信息,内核会试着驱动这些设备。

内核会尝试挂载根文件系统,根文件系统至少包含 /etc /bin /sbin /lib /dev 这5大目录

挂载了根文件系统后,就会启动init服务。

init 程序首先是需要读取配置文件 /etc/inittab(配置文件),根据这个文件的信息来进行初始化工作.。


相关更多可参看:附
3)文件存储

4)性能问题分析案例

5)JVM相关

JVM是Java Virtual Machine(Java虚拟机),它包含了一套字节码指令集,一组寄存器,一个栈,一个垃圾回收堆和一个存储方法域;屏蔽了与宿主具体操作系统平台相关的信息,使Java程序生成的文件(字节码)只需在Java虚拟机上就可运行的,可以在多种平台上不加修改地运行,实现平台无关性。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java语言最重要的特点就是跨平台运行。使用JVM就是为了支持与操作系统无关,实现跨平台。JVM在执行字节码(.class)时,负责把字节码解释成具体平台上的机器指令执行。

(1)JRE(Java Runtime Environment):java平台/运行环境。所有的java程序都要在JRE环境下才能运行。
(2)JDK(Java Development Kit):是开发者用来编译、调试程序用的开发依赖。JDK也是JAVA程序需要在JRE上运行。
(3)JVM(Java Virtual Machine):是JRE的一部分。它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

  • jvm是java的核心和基础,在java编译器和os平台之间的虚拟处理器,可在上面执行字节码程序。
    \
  • java编译器只面向jvm,生成jvm能理解的字节码文件。java源文件经编译成字节码程序,通过jvm将每条指令翻译成不同的机器码,通过特定平台运行。

    JVM执行程序的过程:
    \
  • 加载.class文件;类加载子系统负责从文件系统或者网络中加载Class文件(Class文件在开头有特定标识);类加载器(Class Loader)只负责class文件的加载,至于是否可以运行,由执行引擎(Execution Engine)决定。
    管理并分配内存;加载的类信息存放于一块成为方法区的内存空间。除了类信息之外,方法区还会存放运行时常量池信息,可能还包括字符串字面量和数字常量(这部分常量信息是Class文件中常量池部分的内存映射);
    执行垃圾收集:
    JRE(java运行时环境)由JVM构造的java程序的运行环境,它有自己的运行的生命周期,也有自己的代码和数据空间。
    JVM在整个jdk中处于最底层,负责于操作系统的交互,用来屏蔽操作系统环境,提供一个完整的Java运行环境,JVM实例对应了一个独立运行的java程序,它是进程级别的。启动一个Java程序时,一个JVM实例就产生了,任何一个拥有public static void main(String[] args)函数的class都可以作为JVM实例运行的起点;main()作为该程序初始线程的起点,任何其他线程均由该线程启动。JVM内部有两种线程:守护线程和非守护线程,main()属于非守护线程,守护线程通常由JVM自己使用,java程序也可以表明自己创建的线程是守护线程;当程序中的所有非守护线程都终止时,JVM才退出;若安全管理器允许,程序也可以使用Runtime类或者System.exit()来退出;
    \


  • :运行时的单位。栈是一种快速有效的分配存储方式,访问速度仅次于PC寄存器(程序计数器);解决程序的运行问题,即程序如何执行,或者说如何处理数据。存放基本数据类型的局部变量,以及引用数据类型的对象的引用。JVM直接对java栈的操作只有两个:每个方法执行,伴随着进栈(入栈,压栈);执行结束后的出栈工作;对于栈来说不存在垃圾回收问题;​ java虚拟机规范允许Java栈的大小是动态的或者是固定不变的;可以使用参数-Xss选项来设置线程的最大栈空间,栈的大小直接决定了函数调用的最大可达深度。
  • :是存储的单位。堆解决的是数据存储的问题,即数据怎么放、放在哪儿。对象主要都是放在堆空间的,是运行时数据区比较大的一块。
  • java虚拟机栈(Java Virtual Machine Stack):早期也叫Java栈。 每个线程在创建时都会创建一个虚拟机栈,其内部保存一个个的栈帧(Stack Frame),对应这个一次次的java方法调用。它是线程私有的;主管java程序的运行,它保存方法的局部变量(8种基本数据类型、对象的引用地址)、部分结果,并参与方法的调用和返回。

栈的运行原理:

每个线程都有自己的栈,栈中的数据都是以栈帧(Stack Frame)的格式存在;在线程上正在执行的每个方法都对应各自的一个栈帧
栈帧是一个内存区块,是一个数据集,维系着方法执行过程中的各种数据信息
JVM直接对java栈的操作只有两个,就是对栈帧的压栈和出栈,遵循先进后出/后进先出的和原则。
在一条活动线程中,一个时间点上,只会有一个活动的栈帧。即只有当前正在执行的方法的栈帧(栈顶栈帧)是有效的,这个栈帧被称为当前栈帧(Current Frame),与当前栈帧对应的方法就是当前方法(Current Method)
执行引擎运行的所有字节码指令只针对当前栈帧进行操作
如果在该方法中调用了其他方法,对应的新的栈帧会被创建出来,放在栈的顶端,成为新的当前栈帧。
不同线程中所包含的栈帧是不允许相互引用的,即不可能在另一个栈帧中引用另外一个线程的栈帧
如果当前方法调用了其他方法,方法返回之际,当前栈帧会传回此方法的执行结果给前一个栈帧,接着,虚拟机会丢弃当前栈帧,使得前一个栈帧重新成为当前栈帧
Java方法有两种返回函数的方式,一种是正常的函数返回,使用return指令;另外一种是抛出异常。不管使用哪种方式,都会导致栈帧被弹出。

存储在JVM中的java对象可以被划分为两类:

一类是生命周期较短的瞬时对象,这类对象的创建和消亡都非常迅速(存入新生代)

另一类对象时生命周期非常长,在某些情况下还能与JVM的生命周期保持一致 (存入老年代)

Java堆区进一步细分可以分为新生代(YoungGen)和老年代(OldGen);其中新生代可以分为伊甸园区(Eden)、新生区1(from)和新生区2(to)

本文标签: 思路参考手册系统Linux运维排