监控系统的各方面的性能,保障各类服务的有序运行,是运维工作的重要组成部分,本篇就介绍一些常用的系统监控命令和相关参数的说明
具体包含以下几个部分:
1、进程管理基础
2、进程管理类工具(ps、top、htop、kill)
3、内存监控类工具(vmstat、pmap)
4、系统监控类工具(glances、dstat)
第一章进程管理基础概念 1、进程是什么运行中的程序的一个副本,因为程序可能会同时被运行多次,故可理解为一个副本,每个进程都有生命周期
linux内核存储进程信息的固定格式,被称为task struct(任务结构体)
多个任务的task struct组成的链表,被称为task list(任务列表)
2、cpu和内存的工作模式(个人总结)cpu是分时的:一个进程可占用多少cpu时长,一个cpu在同一时刻只能执行一个任务,CPU自身的寄存器中,存放着正在运行的进程的状态信息,当该进程分配的时间片到了时候,即使该进程没有执行完成,也会被调度出去,让下一个进程放到CPU上去运行,但是对于之前没有执行完成的进程,如果没有一种机制保存下来进程执行到哪里的等等的一些相关信息,那么当下一次轮到该进程执行时,又要重新开始执行,这样是不合理的。为了解决这种问题,就有了保存现场和恢复现场的概念
保存现场就是当正在运行的进程,CPU运行时间到达之后,将进程运行的状态等信息,由内核调度存储到内存中,这就是保存现场
恢复现场就是之前保存过的进程的运行状态的信息,当该进程又获得CPU运行时间时,将保存的状态信息调度到CPU上,这样CPU就能根据保存的状态继续运行进程,而不是从头开始运行进程
内存是分空间的:一个进程可占用多少内存空间,内存分配方式有点类似磁盘,分成很多块,但内存不叫块,而是叫页框(page frame)用于存储页面数据,一般一个page的大小为4K。分配的页框可以有多个,且可以不连续。
进程需要用到内存数据的时候,怎么去找内存中不连续的数据?
因为数据在实际内存中可以不连续,也就是离散的,故一般情况下,内核会虚拟一个内存空间面向进程,进程不需要直接与实际的物理存储的内存打交道,只需与内核虚拟出来的内存打交道,内核虚拟出来的内存的大小,与计算机平台的位数有关系,一般32位系统上,单个进程虚拟出来的内存大小为4G,1G给内核使用,3G给该进程使用;64位系统上,单个进程虚拟出来的内存大小为4G个4G,内核虚拟出来的内存空间叫做线性地址空间,内核虚拟出来的内存对进程而言是连续,且独占的。这样,进程读写内存数据时就认为自己读取的是一个连续的地址空间,且是独占的,这段虚拟出来的空间中,只有真正被使用的部分,内核才会在物理内存上分配空间进行存储
swap分区:为了防止过多的进程将实际物理内存占满导致程序无法运行,从而有了swap交换分区的概念,swap分区实际是用来临时存放内存中暂时用不到的页面数据。置换时,通常采用LRU算法(最近最少使用)将最近最少用到的数据暂存在交换分区中
一次磁盘IO分为两段进行,第一段是将数据从磁盘拿到内存中内核空间,第二段时将内核空间的数据复制一份放到用户空间
3、线程相关概念线程:是一个进程内部的多个执行流,一个执行流就叫一个线程
一个进程只有一个执行流,也可以有线程,这种模式就叫单进程单线程模型
一个进程有多个执行流,就叫单进程多线程模型
如果一个进程有多个执行流,也就是有多个线程,但是如果只有1个CPU,那么也多线程也没有任何意义,因为一个cpu在同一时刻只能同时执行一个任务
同一个进程内部的多个线程,可以共享内存空间。比如web服务,如果是单进程模型,一个进程相应一个用户请求,如果100个用户请求的都是index.html页面,那么在内存上就需要为每个进程存放都存放一个index.html的数据,这样就造成了内存浪费,但是如果是采用单进程多线程模式,这样利用一个线程相应一个用户请求,这样就只需要为这个进程在内存上存储一份index.html的数据,然后多个线程共享这段数据,这样就大大节约了内存的空间
Linux原生对线程的支持性不是特别好
一个进程的数据部分分为指令和数据,程序在执行时,内存中的数据也分指令数据和实际的数据,其中指令数据和部分的实际数据,是不能被交换到交换分区上的,称之为常驻内存集,而有些数据是可以被交换到交换分区上的,称之为虚拟内存集
4、Linux上进程创建模型进程创建:
init进程:初始化进程,后续的所有用户空间进程管理者(所有进程的父进程)
其他进程:除了init进程之外,所有进程都由父进程创建,父进程利用fork()系统调用生成,每个进程都是由父进程fork()自身而来,会clone()自身的数据给子进程
当父进程创建子进程时,子进程和父进程使用的是同一段内存空间;一旦子进程需要对该段内存空间的数据进行修改时,就会复制该段内存空间的数据到另外一段内存空间,子进程就指向了该段新的内存空间
这种机制叫CoW(写时复制),如果子进程不对数据进程修改,跟父进程使用的内存空间都是同一个,但是一旦子进程要修改数据,就复制一份数据到另一块内存供子进程单独使用,而从此之后,子进程就一直使用新的内存空间了
进程的终止:子进程完成一定的任务之后,释放掉自己占用的资源,然后父进程对子进程进行回收
5、进程的优先级:0-139:
1-99:实时优先级
100-139:用户可调度的优先级(数字越小,优先级越高)
nice值:-20到19分别对应100-139,进程初始时nice默认都为0,普通用户只能调低自己的优先级,也就是加大自己的nice值,而管理员用户可以任意指定
修改进程优先级:nice、renice
可调整的区间为100-139
通过调整nice值可以调整进程的优先级:
nice值的范围为-20到19,分别对应进程优先级的100-139
进程启动时的默认nice值都为0,故其默认优先级为120
普通用户:只能调大nice值,也就是降低优先级,不能低于0
管理员:可以任意调整nice值-20到19
怎么调整优先级:
对于尚未启动的程序:
nice -n 数字 COMMAND
表示启动程序时,以指定的数字作为其nice值
对于已经启动的进程:
renice 数字 PID
表示对指定的PID进程调整其nice值为指定数字


6、进程队列
Linux内核为了能够快速的实现这些优先级不同的进程的调度,将待运行的进程按照对应的优先级分成了140个运行队列,每个优先级相同的进程为同一个队列,这样,内核进行调度时,不需要遍历整个队列,而是按照优先级从高到低,取队列的第一个进程进行调度
同时也有140个过期队列,就是将上面运行队列中,调度过的进程,在为其分配的CPU时间片的时间内尚未运行完成,就放到了过期队列,当同优先级的运行队列中的进程都被调度完成后,就会重新调度过期队列,此时过期队列就变成了运行队列
7、进程类型:守护进程:daemon,跟终端无关,由内核在系统引导过程中启动的进程
用户前台进程:用户通过终端启动的进程,跟终端相关
注意:也可把前台启动的进程收网后台,以守护模式运行
8、进程的状态:运行态:running,进程正在运行中
就绪态:ready,可以运行但尚未被运行
睡眠态:sleeping
可中断睡眠:interruptible,调度到CPU上可立即运行起来
不可中断睡眠:uninterruptible 通常是指被IO阻塞的进程,等待IO满足之前无法继续运行
僵死态:zombie,找不到归属,父进程没有回收该进程,父进程就挂了
停止态:stopped 暂停于内存中,不可被调度并运行
9、进程间通信机制(IPC: Inter Process Communication)同一主机上
通过发送信号(通过kill命令):signal
共享内存shm: shared memory
semophore 信号量,一种计数器
不同主机上:
rpc: remote procedure call(NFS就是基于这种机制的)
套接字socket: IP和端口号
10、Linux系统状态的查看及管理工具:pstree, ps, pidof,pgrep, top, htop, glance, pmap, vmstat, dstat, kill,pkill, job, bg, fg, nohup
第二章进程管理类工具(ps、top、htop、kill) 1、ps命令(ps、pgrep、pidof)ps命令:显示系统当前进程的运行情况,实际是将/proc/目录下的各个进程的相关信息转换为我们易读的模式展现出来
选项与参数:
-A 所有的进程都显示出来,与-e具有同样的效果
a 与终端无关的所有进程
u 以用户为中心显示与用户相关的进程信息
x 通常与a一起使用,可列出较完整的信息
输出格式定义:
l 列出详细的信息
j 工作的格式
-f 完整格式列表,做一个更为完整的输出
o 属性选项显示定制的信息:
psr 当前进程运行的CPU编号(四颗CPU就是0、1、2、3)
pri 当前进程的优先级
ni 当前进程的nce值(-20,19),nice值越低,优先级越高
pid 进程号
command 发起进程的命令
state 进程状态
%cpu 占用CPU的百分比
%mem 占用内存的百分比
tty 占用的终端
euser 进程的有效用户
ruser 进程的实际用户
有效用户和实际用户可用于验证设置了SUID权限的二进制程序文件运行时,有效用户为进程文件的属主用户,实际用户为运行程序文件的用户
常用的组合方式:
ps -ef 以完整的信息显示所有进程的信息
ps aux
ps axo
ps aux的显示出来的参数的意义
[root@localhost ~]# ps auxUSER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 19352 1548 ? Ss Sep05 0:01 /sbin/i
root 2 0.0 0.0 0 0 ? S Sep05 0:00 [kthre]
root 3 0.0 0.0 0 0 ? S Sep05 0:00 [migra]
root 4 0.0 0.0 0 0 ? S Sep05 0:00 [ksoft]
root 5 0.0 0.0 0 0 ? S Sep05 0:00 [stopp]
root 6 0.0 0.0 0 0 ? S Sep05 0:00 [watch]
root 7 0.0 0.0 0 0 ? S Sep05 0:00 [migra]
――――――――――――――――――――――――――――――――――――――
USER:进程的发起者
PID:进程号
%CPU:进程占用掉的CPU资源的比例
%MEM:进程所占用的物理内存百分比
VSZ:进程使用掉的虚拟内存的大小,也就是内核虚拟出来的给该进程的线性地址空间的大小,
假如分配给其1000k,或许实际并没有数据占用,单位为kb
RSS:进程占用的固定物理内存的大小,实际占用的内存的大小,常驻内存集,也就是不能交换到swap分区上的数据的大小,单位为kb
一个进程的数据部分分为指令和数据,程序在执行时,内存中的数据也分指令数据和实际的数据,
其中指令数据和部分的实际数据,是不能被交换到交换分区上的,称之为常驻内存集,而有些数
据是可以被交换到交换分区上的,称之为虚拟内存集
TTY:进程在哪个终端运行
STAT:进程目前的状态
各状态的值代表的意义
R 运行状态
S 可中断睡眠态
D 不可中断睡眠态
Z 僵死态
T 停止态
有的进程在进程状态之后还会有其他字母,其分别代表的含义为:
s seesion leader 会话领导者,主进程
N 低优先级进程
< 高优先级进程
l 多线程进程(小写的L)
+ 前台进程,占据着某终端
START:进程被触发的时间
TIME:进程实际使用cpu的时间
COMMAND:触发此进程的命令
ps -ef显示出来的结果代表的意义
[root@localhost ~]# ps -efUID PID PPID C STIME TTY TIME CMD
root 1 0 0 Sep05 ? 00:00:01 /sbin/init
root 2 0 0 Sep05 ? 00:00:00 [kthreadd]
root 3 2 0 Sep05 ? 00:00:00 [migration/0]
root 4 2 0 Sep05 ? 00:00:00 [ksoftirqd/0]
root 5 2 0 Sep05 ? 00:00:00 [stopper/0]
root 6 2 0 Sep05 ? 00:00:00 [watchdog/0]
root 7 2 0 Sep05 ? 00:00:00 [migration/1]
root 8 2 0 Sep05 ? 00:00:00 [stopper/1]
root 9 2 0 Sep05 ? 00:00:00 [ksoftirqd/1]
――――――――――――――――――――――――――――――――――――――
UID:进程发起者的UID
PID:进程号
PPID:进程的父进程ID号
C:CPU利用率,使用时间
STIME:进程的启动时间,就是指从什么时候启动的进程
TTY:登录者的终端位置,远程则显示pts/N 本地则显示ttyN,?代表是系统进程
TIME:进程实际花费CPU的运行时间,不是系统时间
CMD:触发此进程的命令 pgrep命令:(基于ps aux显示出来的结果过滤) 语法:pgrep [OPTIONS] “PATTERN”
选项:
-u uid: effective user,生效者
-U uid: real user,真正发起运行命令者
-t terminal: 与指定终端相关的进程
-l: 显示进程名
-a: 显示完整格式的进程名
-P pid: 显示指定进程的子进程
-G GID|GROUPNAME 仅显示以指定用户组身份运行的进程(只指定该选项只会显示出一列以该组身份运行的PID,配合-l选项使用,可显示进程的PID和进程名)