一、进程状态的管理
当进程运行为进程后,我们可以使用Linux的命令对进程发送关闭信号。
1、使用kill -l 列出当前系统所支持的命令
[root@oldboy:~]# kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
2、最常用的进程管理命令:kill -1 PID、kill -9 PID
数字编号 | 字符表示 | 含义 |
---|---|---|
1 | SIGHUP | 重新加载配置文件 |
9 | SIGKILL | 强制终止(杀死)进程 |
15 | SIGTERM | 终止进程,默认kill的使用 |
1)使用kill 参数 命令终止PID的进程
1.启动vsftpd
[root@oldboy:~]# systemctl start vsftpd
2.静态查看vsftpd的状态
[root@oldboy:~]# ps aux |grep vsftpd
root 7759 0.0 0.0 53176 580 ? Ss 14:53 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
root 7761 0.0 0.0 112708 976 pts/0 R+ 14:54 0:00 grep --color=auto vsftpd
3.发送重载命令,重新加载,其父进程的PID号不发生改变
[root@oldboy:~]# kill -1 7759
[root@oldboy:~]# ps aux |grep vsftpd
root 7759 0.0 0.0 53176 760 ? Ss 14:53 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
root 7763 0.0 0.0 112708 976 pts/0 R+ 14:54 0:00 grep --color=auto vsftpd
4.发送终止信号,vsftpd的服务停止(kill=kill -15)
[root@oldboy:~]# kill 7759
[root@oldboy:~]# ps aux |grep vsftpd
root 7766 0.0 0.0 112708 976 pts/0 R+ 14:59 0:00 grep --color=auto vsftpd
5.当无法停止时,可使用强制的命令将其终止
[root@oldboy:~]# kill -9 7759
3、killall、pkill 终止指定名字的进程
1.我们首先启动nginx服务并查看当前状态
[root@oldboy:~]# systemctl start nginx
[root@oldboy:~]# ps aux |grep nginx
root 7817 0.0 0.0 46340 972 ? Ss 15:05 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx 7818 0.0 0.0 46748 1936 ? S 15:05 0:00 nginx: worker process
root 7820 0.0 0.0 112708 972 pts/1 R+ 15:06 0:00 grep --color=auto nginx
2.通过服务器的名称将其杀掉
[root@oldboy:~]# pkill nginx
[root@oldboy:~]# ps aux |grep nginx
root 7832 0.0 0.0 112708 976 pts/0 R+ 15:10 0:00 grep --color=auto nginx
3.通过killall终止nginx服务
[root@oldboy:~]# killall nginx
[root@oldboy:~]# ps aux |grep nginx
root 7832 0.0 0.0 112708 976 pts/0 R+ 15:10 0:00 grep --color=auto nginx
1)使用pkill 踢出远程登陆的本机的用户,终止 /pts/1上的所有进程并结束bash
1.打开2个bash shell的窗口
[root@oldboy:~]# tty
/dev/pts/0
[root@oldboy:~]# tty
/dev/pts/1
2.利用pkill 将远程登陆的bashshell窗口 /pts/1踢下线
[root@oldboy:~]# pkill -9 -t pts/1
[root@oldboy:~]#
Connection closed by foreign host.
Disconnected from remote host(oldboy-65 - cui) at 15:29:07.
Type `help' to learn how to use Xshell prompt.
[c:\~]$
二、进程后台管理
1、什么是后台进程
通常进程都会在终端前台运行,一旦关闭终端,进程也会随之结束,这样比较浪费资源。那么我们希望将进程放入终端后台,关闭终端后,进行进程继续运行。减少资源的浪费。
2、将进程放入后台的命令:$符、jobs、bg、fg、最常用的screen
1)使用jobs、bg、fg
1.运行2个程序,一个在后台执行,一个在后台执行
[root@oldboy:~]# sleep 3000 & 程序运行在后台执行
[1] 7940
[root@oldboy:~]# sleep 4000 将前台程序挂起在后台
^Z
[3]+ Stopped sleep 4000
2.静态查看sleep的状态
[root@oldboy:~]# ps aux |grep sleep
root 7940 0.0 0.0 107952 360 pts/1 S 15:39 0:00 sleep 3000
root 7942 0.0 0.0 107952 356 pts/1 T 15:41 0:00 sleep 4000
3.利用jobs查看后台作业情况
[root@oldboy:~]# jobs
[1]- Running sleep 3000 &
[3]+ Stopped sleep 4000
4.利用bg 和 fg 进行前后台调动
[root@oldboy:~]# bg %3 让作业 3 在后台运行
[3]+ sleep 4000 &
[root@oldboy:~]# fg %1 将作业 1 调回前台
sleep 3000
5.终止作业1,利用PID
[root@oldboy:~]# kill 7940
2)利用screen 进行后台管理
1.安装screen
[root@oldboy ~]# yum install screen -y
2.开启一个screen窗口,指定名称
[root@oldboy ~]# screen -S wget_mysql
3.在screen窗口中执行任务即可
[root@oldboy ~]#
4.ctrl+a+d平滑的退出screen,但不会终止screen中的任务。注意: 如果使用exit或者Ctrl+d 才算真的关闭screen窗口
5.查看当前正在运行的screen有哪些
[root@oldboy ~]# screen -list
There is a screen on:
22058.wget_mysql (Detached)
1 Socket in /var/run/screen/S-root.
6.进入正在运行的screen
[root@oldboy ~]# screen -r wget_mysql
[root@oldboy ~]# screen -r 22058
7.终止当前后台运行的进程,将后台运行的程序调回前台,Ctrl+c 终止然后exit退出;或者Ctrl+c后Ctrl+d退出。
三、进程的优先级
优先级是指在CPU处理进程调度时,优先处理优先级较高的进程。
1、配置优先级 命令 nice
在启动进程时,为不同的进程使用不同的调度策略。
nice 值越高: 表示优先级越低,例如+19,该进程容易将CPU 使用量让给其他进程。
nice 值越低: 表示优先级越高,例如-20,该进程更不倾向于让出CPU。
NI =0 PR=20
NI =-20 PR=0
NI = 10 PR=30
NI = 19 PR =39
1)使用top或者ps命令进行查看进程的优先级
1、使用top可以查看nice优先级。 NI: 实际nice级别,默认是0。 PR: 显示nice值,-20映射到0,+19映射到39
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
7912 root 20 0 0 0 0 S 0.3 0.0 0:08.41 kworker/0:3
1 root 20 0 125732 4264 2600 S 0.0 0.2 0:05.59 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:00.29 ksoftirqd/0
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
7 root rt 0 0 0 0 S 0.0 0.0 0:00.00 migration/0
2、使用ps查看进程优先级
[root@oldboy:~]# ps axo command,nice
COMMAND NI
/usr/lib/systemd/systemd -- 0
[kthreadd] 0
[ksoftirqd/0] 0
[kworker/0:0H] -20
[migration/0] -
[rcu_bh] 0
[rcu_sched] 0
[lru-add-drain] -20
[watchdog/0] -
[kdevtmpfs] 0
[netns] -20
2) nice指定程序的优先级。语法格式 nice -n + 优先级数字 + 进程名称
1.设定vim的优先级为 -5
[root@oldboy:~]# nice -n -5 vim &
[1] 8031
2.查看进程 vim 的优先级
[root@oldboy:~]# ps axo command,nice|grep "vim"
vim -5
grep --color=auto vim
3)renice 命令修改一个正在运行的进程优先级。语法格式 renice -n + 优先级数字 + 进程pid
1.查看sshd进程当前的优先级状态
[root@oldboy:~]# ps axo pid,command,nice|grep sshd
7358 /usr/sbin/sshd -D 0
7620 sshd: root@pts/0 0
7914 sshd: root@pts/1 0
8054 grep --color=auto sshd 0
2.调整sshd主进程的优先级
[root@oldboy:~]# renice -n -20 7358
7358 (process ID) old priority 0, new priority -20
3.调整之后查看并退出终端
[root@oldboy:~]# ps axo pid,command,nice|grep sshd
7358 /usr/sbin/sshd -D -20
7620 sshd: root@pts/0 0
7914 sshd: root@pts/1 0
8057 grep --color=auto sshd 0
[root@oldboy:~]# exit
4.当再次登陆sshd服务,会由主进程fork子进程(那么子进程会继承主进程的优先级)
[root@oldboy:~]# ps axo pid,command,nice|grep sshd
7358 /usr/sbin/sshd -D -20
7914 sshd: root@pts/1 0
8065 sshd: root@pts/0 -20
8091 grep --color=auto sshd -20
当服务器响应较慢时,通过对登录的sshd协议调度nice优先级的设置,可让让我们在系统出现服务故障时,第一时间优先登录系统检查系统的故障。
4)服务器的假死
所谓假死,就是我们可ping通服务器,但是ssh登录不上去,任何其他操作也没有反应,非常的缓慢。包括上面部署的nginx的页面也没有反应。
2、平均负载
平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数, 平均负载与 CPU 使用率并没有直接关系。
[root@oldboy:~]# uptime
19:01:41 up 4:13, 3 users, load average: 0.00, 0.01, 0.05
1)如何判断平均负载
最理想的状态是每个 CPU 上都刚好运行着一个进程,这样每个 CPU 都得到了充分利用。所以在评判平均负载时,首先你要知道系统有几个 CPU,这可以通过 top 命令获取,或grep 'model name' /proc/cpuinfo
2)平均负载的三个指标
1.如果 1 分钟、5 分钟、15 分钟的三个值基本相同,或者相差不大,那就说明系统负载很平稳。
2.但如果 1 分钟的值远小于 15 分钟的值,就说明系统最近 1 分钟的负载在减少,而过去 15 分钟内却有很大的负载。
3.反过来,如果 1 分钟的值远大于 15 分钟的值,就说明最近 1 分钟的负载在增加,这种增加有可能只是临时性的,也有可能还会持续上升,所以就需要持续观察。
示例
假设我们在有2个 CPU 系统上看到平均负载为 2.73,6.90,12.98
- 那么说明在过去1 分钟内,系统有 136% 的超载 (2.73/2=136%)
- 而在过去 5 分钟内,有 345% 的超载 (6.90/2=345%)
- 而在过去15 分钟内,有 649% 的超载,(12.98/2=649%)
但从整体趋势来看,系统的负载是在逐步的降低。
3)那么在实际生产环境中,平均负载多高时,需要重点关注
当平均负载高于 CPU 数量 70% 的时候,就应该分析排查负载高的问题了。一旦负载过高,就可能导致进程响应变慢,进而影响服务的正常功能。
但 70% 这个数字并不是绝对的,把系统的平均负载监控起来,然后根据更多的历史数据,判断负载的变化趋势。当发现负载有明显升高趋势时,比如说负载翻倍了,再去做分析和调查。
4)平均负载与 CPU 使用率的关系
我们还是要回到平均负载的含义上来,平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数。所以,它不仅包括了正在使用 CPU 的进程,还包括等待 CPU 和等待 I/O 的进程。
1、而 CPU 使用率,是单位时间内 CPU 繁忙情况的统计,跟平均负载并不一定完全对应。比如:
2、CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者是一致的;
3、I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高;
4、大量等待 CPU 的进程调度也会导致平均负载升高,此时的 CPU 使用率也会比较高。
5)平均负载案例分析实战
下面,我们以三个示例分别来看这三种情况,并用 stress、mpstat、pidstat 等工具,找出平均负载升高的根源。
1.stress 是 Linux 系统压力测试工具,这里我们用作异常进程模拟平均负载升高的场景。
2.mpstat 是多核 CPU 性能分析工具,用来实时查看每个 CPU 的性能指标,以及所有 CPU 的平均指标。
3.pidstat 是一个常用的进程性能分析工具,用来实时查看进程的 CPU、内存、I/O 以及上下文切换等性能指标。
如果出现无法使用mpstat、pidstat命令查看%wait指标建议更新下软件包
wget http://pagesperso-orange.fr/sebastien.godard/sysstat-11.7.3-1.x86_64.rpm
rpm -Uvh sysstat-11.7.3-1.x86_64.rpm
场景一:CPU 密集型进程
1.首先,我们在第一个终端运行 stress 命令,模拟一个 CPU 使用率 100% 的场景:
[root@oldboy:~]# stress --cpu 1 --timeout 600
2.接着,在第二个终端运行 uptime 查看平均负载的变化情况
使用watch -d 参数表示高亮显示变化的区域(注意负载会持续升高)
[root@oldboy:~]# watch -d uptime
17:27:44 up 2 days, 3:11, 3 users, load average: 1.10, 0.30, 0.17
3.最后,在第三个终端运行 mpstat 查看 CPU 使用率的变化情况
-P ALL 表示监控所有 CPU,后面数字 5 表示间隔 5 秒后输出一组数据
[root@oldboy:~]# mpstat -P ALL 5
Linux 3.10.0-957.1.3.el7.x86_64 (m01) 2019年04月29日 _x86_64_ (1 CPU)
17时32分03秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
17时32分08秒 all 99.80 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00
17时32分08秒 0 99.80 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00
单核CPU所以只有一个all和0
4.从终端二中可以看到,1 分钟的平均负载会慢慢增加到 1.00,而从终端三中还可以看到,正好有一个 CPU 的使用率为 100%,但它的 iowait 只有 0。这说明,平均负载的升高正是由于 CPU 使用率为 100% 。那么,到底是哪个进程导致了 CPU 使用率为 100% 呢?可以使用 pidstat 来查询
间隔 5 秒后输出一组数据
[root@oldboy:~]# pidstat -u 5 1
Linux 3.10.0-957.1.3.el7.x86_64 (m01) 2019年04月29日 _x86_64_(1 CPU)
17时33分21秒 UID PID %usr %system %guest %CPU CPU Command
17时33分26秒 0 110019 98.80 0.00 0.00 98.80 0 stress
从这里可以明显看到,stress 进程的 CPU 使用率为 100%。
场景二:I/O 密集型进程
1.首先还是运行 stress 命令,但这次模拟 I/O 压力,即不停地执行 sync
[root@oldboy:~]# stress --io 1 --timeout 600s
2.然后在第二个终端运行 uptime 查看平均负载的变化情况:
[root@oldboy:~]# watch -d uptime
18:43:51 up 2 days, 4:27, 3 users, load average: 1.12, 0.65, 0.00
3.最后第三个终端运行 mpstat 查看 CPU 使用率的变化情况:
# 显示所有 CPU 的指标,并在间隔 5 秒输出一组数据
[root@oldboy:~]# mpstat -P ALL 5
Linux 3.10.0-693.2.2.el7.x86_64 (bgx.com) 2019年05月07日 _x86_64_ (1 CPU)
14时20分07秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
14时20分12秒 all 0.20 0.00 82.45 17.35 0.00 0.00 0.00 0.00 0.00 0.00
14时20分12秒 0 0.20 0.00 82.45 17.35 0.00 0.00 0.00 0.00 0.00 0.00
#会发现cpu的与内核打交道的sys占用非常高
4.那么到底是哪个进程,导致 iowait 这么高呢?我们还是用 pidstat 来查询
# 间隔 5 秒后输出一组数据,-u 表示 CPU 指标
[root@oldboy:~]# pidstat -u 5 1
Linux 3.10.0-957.1.3.el7.x86_64 (m01) 2019年04月29日 _x86_64_(1 CPU)
18时29分37秒 UID PID %usr %system %guest %wait %CPU CPU Command
18时29分42秒 0 127259 32.60 0.20 0.00 67.20 32.80 0 stress
18时29分42秒 0 127261 4.60 28.20 0.00 67.20 32.80 0 stress
18时29分42秒 0 127262 4.20 28.60 0.00 67.20 32.80 0 stress
#可以发现,还是 stress 进程导致的。
场景三:大量进程的场景
当系统中运行进程超出 CPU 运行能力时,就会出现等待 CPU 的进程。
1.首先,我们还是使用 stress,但这次模拟的是 4 个进程
[root@oldboy:~]# stress -c 4 --timeout 600
2.由于系统只有 1 个 CPU,明显比 4 个进程要少得多,因而,系统的 CPU 处于严重过载状态
[root@oldboy:~]# watch -d uptime
19:11:07 up 2 days, 4:45, 3 users, load average: 4.65, 2.65, 4.65
3.然后,再运行 pidstat 来看一下进程的情况:
# 间隔 5 秒后输出一组数据
[root@oldboy:~]# pidstat -u 5 1
平均时间: UID PID %usr %system %guest %wait %CPU CPU Command
平均时间: 0 130290 24.55 0.00 0.00 75.25 24.55 - stress
平均时间: 0 130291 24.95 0.00 0.00 75.25 24.95 - stress
平均时间: 0 130292 24.95 0.00 0.00 75.25 24.95 - stress
平均时间: 0 130293 24.75 0.00 0.00 74.65 24.75 - stress
可以看出,4 个进程在争抢 1 个 CPU,每个进程等待 CPU 的时间(也就是代码块中的 %wait 列)高达 75%。这些超出 CPU 计算能力的进程,最终导致 CPU 过载。