一个完整的计算机系统:静态
最底层是硬件,硬件之上是操作系统,也叫内核(即kernel),操作系统提供的是系统调用,在内核之上,是各种库,提供库函数,在此之上是各种应用程序,应用程序可能是基于库函数实现的,也可能直接使用系统调用。
x86引入了访问特权等级(0-3)的机制,x86 cpu共有4个特权级 level0 到 level3 ,也称为ring0~ring3,其中level0特权级最高,level3特权级最低。level0(即ring0,特权指令)只能由内核执行,处理器通过识别CPL、DPL、RPL这3中种特权级进行特权级检验。
内核的功能:进程管理、文件系统、网络功能、内存管理、驱动程序、安全功能
一个程序运行分为用户模式和内核模式,用户模式下,cpu运行用户指令,当程序需要用到内核功能时,就会调用系统调用,进入内核模式,cpu运行内核指令。
模式切换:从用户模式到内核模式和从内核模式到用户模式的切换。
时间片:每个进程不能始终占有cpu,而是使用一段固定的时间,即时间片。
进程切换:多个进程同时运行,轮流使用cpu,就是进程切换。
保存现场:进程切换时,需要保存进程的状态,以便下次能够接续执行。
恢复现场:再次执行中断的进程,需要先恢复上次保存现场的状态。
Process(进程):运行中的程序的副本;进程有自己的生命周期。(程序是静态的文件)
内核要为每一个运行的进程创建一个元数据,存储进程状态信息,格式是固定的,叫做任务结构体,task struct,多个任务的task struct组成的链表:task list
进程创建:内核加载完毕,创建第一个进程init,来管理用户空间
init
父子关系:进程都由其父进程创建,父进程调用fork(),创建子进程,子进程与父进程一开始拥有相同的空间,当子进程需要修改数据时,发生写时拷贝(CoW),clone()父进程,然后指向克隆后的起始空间,执行自己的修改操作。
进程优先级:0~139
1-99:实时优先级:(数字越大,优先级越高)
100-139:静态优先级(数字越小,优先级越高)
Nice值:-20~19
内存分配:page frame:页框,线性地址空间,物理地址空间。
MMU:Memory Management Unit,线性地址到物理地址映射
IPC:Inter Process Communication
同一主机:signal、shm——shared memory、semerphor
不同主机:rpc——remote procedure call、socket
Linux内核:抢占式多任务
进程类型:
守护进程:daemon,在系统引导过程中启动的进程,跟终端无关的进程;
前台进程:跟终端相关,通过终端启动的进程。
注意:也可把在前台启动的进程送往后台,以守护模式运行。
进程状态:
运行态:running
就绪态:ready
睡眠态:一次I/O需要两步:从磁盘到内核内存,从内核内存到用户内存。
可中断:interruptable
不可中断:uninterruptable
停止态:暂停于内存中,但不会被调度,除非手动启动之:stopped
僵死态:zombie
进程的分类:
CPU-Bound:多分CPU时间片
IO-Bound:优先级高
Linux进程查看及管理的工具:pstree、ps、pidof、pgrep、top、htop、glance、pmap、vmstat、dstat、kill、pkill、job、bg、fg、nohup
pstree:显示进程树
Centos7中:起始进程是systemd
Centos6中:起始进程是init
ps:process state,进程状态查看工具。report a snapshot of the current processes
每一个进程都会映射到/proc目录下的一个数字目录,对应的这个数字目录下有一个cmdline文件,说明启动这个进程的命令:
目录中还包含其他一些文件,包含了更多的信息,Linux系统各进程的相关信息均保存在/proc/PID目录下的各文件中。因为这些文件及信息相对复杂,于是就有了各种进程查看工具,都是来遍历这个目录,以不同格式显示相关信息。
ps [OPTION] ...
选项:支持两种风格
常用组合:aux
u:以用户为中心组织进程状态信息显示
a:与终端相关的进程
x:与终端无关的进程
[root@localhost ~]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.2 1.5 128932 7636 ? Ss 15:26 0:06 /usr/lib/systemd/systemd -
root 2 0.0 0.0 0 0 ? S 15:26 0:00 [kthreadd]
VSZ:Virtual memory SiZe,虚拟内存集
RSS:ReSident Size,常驻内存集
STAT:进程状态
R:running
S:interruptable sleeping
D:uninterruptable sleeping
T:stopped
Z:zombie
+:前台进程
l:多线程进程
N:低优先级进程
<:高优先级进程
s:session leader
START:启动时间
TIME:运行占用CPU的累积时间
COMMAND:启动进程的命令
常用组合:-ef
-e:显示所有进程
-f:显示完整格式程序信息
常用组合:-ejH
以进程层级格式显示进程相关信息
常用组合:-eFH
-F:显示更完整格式的进程信息
-H:层级显示进程
常用组合:-eo,axo
-o:自定义显示字段
ps -eo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,comm
ps axo stat,euid,ruid,tty,tpgid,sess,pgrp,ppid,pid,pcpu,comm
ni:nice值
pri:priority,优先级
psr:processor,CPU
rtprio:实时优先级
pgrep、pkill:
pgrep [options] pattern
pkill [options] pattern
-u uid:effective user
-U uid:real user
-t terminal:与指定终端相关的进程
-l:显示进程名
-a:显示完整格式的进程名
-P pid:显示其父进程为此处指定的进程的进程列表
pidof:根据进程名获取其进程id
top:动态显示进程信息
有许多内置命令:
排序:
P:以占据的CPU百分比;
M:占据内存百分比
T:累积占用CPU时间
首部信息显示:
uptime信息:l命令
tasks及cpu信息:t,cpu分别显示:1(数字)
memory信息:m命令
退出命令:q
修改刷新时间间隔命令:s
终止指定进程命令:k
top选项:
-d #:指定刷新时间间隔,默认3秒
-b:以批次方式显式
-n #:显示多少批次
top - 16:51:50 up 1:25, 1 user, load average: 0.01, 0.04, 0.05
Tasks: 138 total, 1 running, 137 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.2 sy, 0.0 ni, 99.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 479624 total, 17512 free, 300072 used, 162040 buff/cache
KiB Swap: 2097148 total, 2096628 free, 520 used. 160672 avail Mem
scroll coordinates: y = 1/138 (tasks), x = 1/12 (fields)
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
htop:注意,需要epel源安装
s:跟踪选定进程的系统调用
l:显示选定进程打开的文件列表
a:将选定的进程绑定至某指定CPU核心
t:显示进程树
vmstat:
vmstat [-n] [延时[次数]]
选项 -s:统计数据
procs:
r:等待运行的进程的个数
b:处于不可中断睡眠态的进程个数(被阻塞的队列的长度)
memory:
swap:交换内存的使用总量
free:空闲物理内存总量
buff:用于buffer的内存总量
cache:用于cache的内存总量
swap:
si:数据进入swap中的数据速率(kb/s)
so:数据离开swap中的数据速率
io:
bi:从块设备读入数据到系统的速率(kb/s)
bo:保存数据至块设备的速率
system:
in:interrupts,中断速率
cs:context switch,进程切换速率
cpu:
us:用户空间占用CPU的比例
sy:内核空间占用CPU的比例
id:空闲比例
wa:等待IO完成占用的CPU比例
st:被虚拟化偷走的CPU比例
pmap:report memory map of a process
pmap [options] pid
-x:显示详细格式的信息
实际上,在/proc/pid/目录下有maps文件,记录了进程的内存映射关系,pmap也就是对此文件的格式化输出。
glances:
常用选项:
-b:以Byte为单位显示网卡数据速率
-d:关闭磁盘I/O模块
-f /path/to/somefile:设定输入文件位置及其格式
-o {HTML | CSV}:输出格式
-m :禁用mount模块
-n : 禁用网络模块
-t #:刷新时间间隔
-1:每个cpu的相关数据单独显示
C/S模式下运行glances命令:
服务模式:
glances -s -B IPADDR
客户端模式:
glances -c IPADDR
dstat:vmstat的替代工具
dstat [-afv] [options..] [delay [count]]
-c:显示cpu信息
-C #,#,...total
-d:显示磁盘相关信息
-D total,sda,...
-g:显示page相关统计数据
-i:显示中断的统计信息
-m:显示memory相关统计数据
-n:显示网络相关统计数据
-p:显示进程相关统计数据
-r:显示IO相关统计数据
-s:显示swapped相关统计数据
--tcp、--udp、--unix、--raw、--socket:显示与tcp、udp、unix、raw相关的进程,socket相当于前四种合计
--ipc:显示进程间通讯的进程
--top-cpu:最消耗cpu的进程
--top-io:最消耗io的进程
--top-mem:最消耗mem的进程
--top-lantency:显示延迟最大进程
kill:向进程发送控制信号,以实现对进程管理
显示当前系统的可用信号:kill -l 或 man7 signal
常用信号:
1)SIGHUP:无须关闭进程而让其重读配置文件
2)SIGINT:中止正在运行的进程,相当于Ctrl+c
9)SIGKILL:杀死正在运行的进程
15)SIGTERM:终止正在运行的进程
18)SIGCONT:
19)SIGSTOP:
指定信号的方法:
(1)信号的数字标识:1,2,9
(2)信号的完整名称:SIGHUP
(3)信号的简写名称:HUP
向进程发信号:
kill [-SIGNAL] PID...
终止“名称”之下的所有进程:
killall [-SIGNAL] program
Linux的作业控制,作业jobs
前台作业:通过终端启动,且启动后一直占据终端(ctrl+z转后台)
后台作业:可以通过终端启动,但启动后即转入后台运行(释放终端)
如何让作业运行于后台?
(1)运行中的作业:Ctrl+z,(输入fg再调回前台)
(2)尚未启动的作业:COMMAND &
此类作业虽然被送往后台运行,但其依然与终端相关:终端终止,作业终止
如果希望送往后台后,剥离与终端的关系:nohup COMMAND &
查看所有作业:
# jobs
作业控制:
# fg [[%]JOB_NUM]:把指定的后台作业调回前台;
# bg [[%]JOB_NUM]:让送往后台的作业在后台继续运行
# kill [%JOB_NUM]:终止指定的作业
进程优先级调整:
静态优先级:100-139
进程默认启动时的nice值为0,优先级为120;
nice命令:
nice [OPTION]... [COMMAND [ARG]...]
nice -n 5 htop
renice命令:
renice [-n] priority pid...
查看:
ps axo pid,comm,ni
其他进程管理工具:sar,tsar,iostat,iftop
sar(System Activity Reporter 系统活动情况报告)可以从多方面对系统的活动进行报告,包括:文件的读写情况、系统调用的使用情况、磁盘 I/O、CPU 效率、内存使用状况、进程活动及 IPC 有关的活动等。
sar [ 选项 ] [ <时间间隔> [ <次数> ] ]
主选项和报告:
-b I/O 和传输速率信息状况
-B 分页状况
-d 块设备状况
-I { <中断> | SUM | ALL | XALL }
中断信息状况
-m 电源管理信息状况
-n { <关键词> [,...] | ALL }
网络统计信息
关键词可以是:
DEV 网卡
EDEV 网卡 (错误)
NFS NFS 客户端
NFSD NFS 服务器
SOCK Sockets (套接字) (v4)
IP IP 流 (v4)
EIP IP 流 (v4) (错误)
ICMP ICMP 流 (v4)
EICMP ICMP 流 (v4) (错误)
TCP TCP 流 (v4)
ETCP TCP 流 (v4) (错误)
UDP UDP 流 (v4)
SOCK6 Sockets (套接字) (v6)
IP6 IP 流 (v6)
EIP6 IP 流 (v6) (错误)
ICMP6 ICMP 流 (v6)
EICMP6 ICMP 流 (v6) (错误)
UDP6 UDP 流 (v6)
-q 队列长度和平均负载
-r 内存利用率
-R 内存状况
-S 交换空间利用率
-u [ ALL ]
CPU 利用率
-v Kernel table 状况
-w 任务创建与系统转换统计信息
-W 交换信息
-y TTY 设备状况
-o {<文件路径>}
将命令结果以二进制格式存放在指定文件中
tsar(Taobao System Activity Reporter)是淘宝自己开发的一个采集工具(类似于sar工具),主要用来收集服务器的系统信息(如cpu,io,mem,tcp等),以及应用数据(如squid haproxy nginx等)。
iostat,报告中央处理器(CPU)统计信息、整个系统、适配器、TTY 设备、磁盘 CD-ROM、磁带和文件系统的异步输入/输出(AIO)与输入/输出统计信息。
iostat [ -c ] [ -d ] [ -h ] [ -k | -m ] [ -N ] [ -t ] [ -V ] [ -x ] [ -y ] [ -z ] [ -j {
ID | LABEL | PATH | UUID | ... } ] [ [ -T ] -g group_name ] [ -p [ device [,...] | ALL ]
] [ device [...] | ALL ] [ interval [ count ] ]
-c: 仅显示CPU利用率相关信息;
-d: 仅显示磁盘I/O相关信息;
-k: 显示输出的数据单位为KB/s而不是默认的字节/s;
-t: 在输出中显示时间戳(时间戳格式YYYY-MM-DD HH:MM:SS)。
-m:显示状态以兆字节每秒为单位;
-p:仅显示块设备和所有被使用的其他分区的状态;
-V:显示版号并退出;
-x:显示扩展状态。
iftop:查看网络流量信息工具
iftop -h | [-nNpblP] [-u unit] [-i interface] [-f filter code] [-F net/mask] [-G
net6/mask6]
iftop相关参数说明:
-i设定监测的网卡,如:# iftop -i eth1
-B 以bytes为单位显示流量(默认是bits),如:# iftop -B
-n使host信息默认直接都显示IP,如:# iftop -n
-N使端口信息默认直接都显示端口号,如: # iftop -N
-F显示特定网段的进出流量,如# iftop -F 172.30.1.0/24或# iftop -F 172.30.1.0/255.255.255.0
-h(display this message),帮助,显示参数信息
-p使用这个参数后,中间的列表显示的本地主机信息,出现了本机以外的IP信息;
-b使流量图形条默认就显示;
-f这个暂时还不太会用,过滤计算包用的;
-P使host信息及端口信息默认就都显示;
-m设置界面最上边的刻度的最大值,刻度分五个大段显示,例:# iftop -m 100M
6.进入iftop画面后的一些操作命令(注意大小写哟~)
按h切换是否显示帮助;
按n切换显示本机的IP或主机名;
按s切换是否显示本机的host信息;
按d切换是否显示远端目标主机的host信息;
按t切换显示格式为2行/1行/只显示发送流量/只显示接收流量;
按N切换显示端口号或端口服务名称;
按S切换是否显示本机的端口信息;
按D切换是否显示远端目标主机的端口信息;
按p切换是否显示端口信息;
按P切换暂停/继续显示;
按b切换是否显示平均流量图形条;
按B切换计算2秒或10秒或40秒内的平均流量;
按T切换是否显示每个连接的总流量;
按l打开屏幕过滤功能,输入要过滤的字符,比如ip,按回车后,屏幕就只显示这个IP相关的流量信息;
按L切换显示画面上边的刻度;刻度不同,流量图形条会有变化;
按j或按k可以向上或向下滚动屏幕显示的连接记录;
按1或2或3可以根据右侧显示的三列流量数据进行排序;
按<根据左边的本机名或IP排序;
按>根据远端目标主机的主机名或IP排序;
按o切换是否固定只显示当前的连接;
按f可以编辑过滤代码,这是翻译过来的说法,我还没用过这个!
按!可以使用shell命令,这个没用过!没搞明白啥命令在这好用呢!
按q退出监控。
中间的<= =>这两个左右箭头,表示的是流量的方向。
TX:发送流量
RX:接收流量
TOTAL:总流量
Cumm:运行iftop到目前时间的总流量
peak:流量峰值
rates:分别表示过去 2s 10s 40s 的平均流量
Linux任务计划、周期性任务执行
未来的某时间点执行一次任务:at、batch
周期性运行某任务:cron
邮件服务:
smtp:simple mail transmission Protocol,用于传送邮件
pop3:Post Office Protocol,
imap4:Internet Mail Access Protocol,
MUA:Mail User Agent
mailx [-s 'SUBJECT'] username[@hostname]
邮件正文的生成:
1)直接给出,Ctrl+d退出
2)输入重定向;
3)通过管道:echo -e “How are you?\nHow old are you?” | mail
at命令:
at [option] TIME
TIME:
HH:MM [YYYY-mm-dd]
noon,midnight,teatime
tomorrow
now+#{minutes,hours,days,OR weeks}
常用选项:
-q QUEUE:
-l:列出队列中等待运行的作业,相当于atq
-d:删除指定的作业,相当于atrm
-c:查看具体作业任务
-f /path/from/somefile:从指定的文件中读取任务
注意:作业的执行结果以邮件通知给相关用户。
因为at是后台运行,其与终端脱离,所以运行的任务命令要注意其路径,最好是写绝对路径,或者设置好环境变量。
batch命令:
让系统自行选择空闲时间去执行此处指定的任务;
周期性任务计划:cron
相关的程序包:
cronie:主程序包,提供了crond守护进程及相关辅助工具
cronie-anacron:cronie的补充程序,用于监控cronie任务执行状况;如果cronie中的任务在过去该运行的时间点未能正常运行,则anacron会随后启动一次此任务;
crontabs:包含CentOS提供系统维护任务;
确保crond守护处于运行状态:
CentOS 7:systemctl status crond
CentOS 6:service crond status
计划要周期性执行的任务提交给crond,由其来实现到点运行。
系统cron任务:系统维护作业
/etc/crontab文件
用户cron任务:
crontab命令
系统cron:
示例:晚上9点10分运行echo命令
10 21 * * * root /bin/echo "Hello!" #使用命令绝对路径,上图所示,PATH只给了四个
时间表示法:
(1)特定值:给定时间点有效取值范围内的值
(2)* :给定时间点上有效取值范围内的所有值;表示“每...”
(3)离散取值:#,#,#
(4)连续取值:- ,如#-#
(5)在指定时间范围上,定义步长:/#,#即为步长
示例:每3小时执行echo
1 */3 * * * root /bin/echo "hello" # 小范围的位置给一个任意具体的值,如果用*,表示每3小时中的每1分钟执行,分钟域写1,代表每3小时的第1分钟执行。
使用crontab -e命令编辑
用户cron:
crontab命令定义,每个用户都有专用的cron任务文件:/var/spool/cron/USERNAME
crontab命令:
crontab [-u user] [-l | -r | -e] [-i]
-l:列出所有任务
-e:编辑任务
-r:删除所有任务
-i:同-r一同使用,以交互式模式让用户有选择移除指定任务
-u user:仅root可运行,代为为指定用户管理cron任务
注意:运行结果以邮件通知给相关用户:
如果不想发邮件:
(1)COMMAND > /dev/null
(2)COMMAND &> /dev/null
对于cron任务来说,%有特殊用途,如果在命令中要使用%,则需要转义,但如果把%放置于单引号中,可以不用转义。
问题:
1)如何在秒级别运行任务?
* * * * * for min in 0 1 2;do echo "hi";sleep 20;done
2)如何实现每7分钟运行一次任务?(不能被所在位取值范围整除)
自编写脚本,使用sleep命令
sleep命令:
sleep NUMBER [SUFFIX]...
SUFFIX:s——秒,默认;m——分;h——小时;d——天