【进程管理】

进程管理

什么是进程?

进程其实就是正在被运行的程序。

  • 1.当程序运行为进程后,系统会为该进程分配内存,以及进程运行的身份和权限
  • 2.在程序运行的过程中,系统会有各种指标来表示当前运行的状态

程序和进程的区别

  • 1.程序:是数据和指令的集合。是一个静态的概念,可以永久存储在系统中。
  • 2.进程:是一个动态的概念,表示程序运行的过程,当我们结束该进程,进程就随之被销毁。

进程的生命周期

  • 进程的生命周期表示进程在系统中的存活时间。
    • 一个进程的上一级进程叫做父进程,用ppid表示。
    • 一个进程的下一级进程叫做子进程,用pid表示。

在这里插入图片描述

  • 1.孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
  • 2.僵尸进程:表示子进程在处理代码过程中异常退出,但是父进程却没有回收子进程,这样的进程便是僵尸进程。僵尸进程的存在会导致子进程虽然实体已经消失,但仍然在进程表中占据一条记录,长期这样会导致系统资源的浪费。僵尸进程无法被常规手段清理,只能通过重启来清理。

监控进程状态

  • 查看进程的状态分为两种:
    • 1.静态查看——> ps:表示查看某一时刻的进程状态
    • 2.动态查看——> top:表示实时监控进程状态。

静态查看进程ps

常用组合: ps -aux
 查看进程用户,PID,占用CPU百分比,占用内存百分比,状态,执行的命令等
 
-a	显示所有终端机下执行的程序,除了阶段作业领导者之外
-u	以用户为主的格式来显示程序状况
-x	显示所有程序,不以终端机来区分
每列含义详解
[root@localhost ~]# ps -aux
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.3  46224  6728 ?        Ss   17:21   0:01 /usr/lib/systemd/syst
root          2  0.0  0.0      0     0 ?        S    17:21   0:00 [kthreadd]
root          4  0.0  0.0      0     0 ?        S<   17:21   0:00 [kworker/0:0H]
root          6  0.0  0.0      0     0 ?        S    17:21   0:00 [ksoftirqd/0]
root          7  0.0  0.0      0     0 ?        S    17:21   0:00 [migration/0]
root          8  0.0  0.0      0     0 ?        S    17:21   0:00 [rcu_bh]
root          9  0.0  0.0      0     0 ?        S    17:21   0:00 [rcu_sched]
root         10  0.0  0.0      0     0 ?        S<   17:21   0:00 [lru-add-drain]
root         11  0.0  0.0      0     0 ?        S    17:21   0:00 [watchdog/0]
root         12  0.0  0.0      0     0 ?        S    17:21   0:00 [watchdog/1]
root         13  0.0  0.0      0     0 ?        S    17:21   0:00 [migration/1]
root         14  0.0  0.0      0     0 ?        S    17:21   0:00 [ksoftirqd/1]
root         16  0.0  0.0      0     0 ?        S<   17:21   0:00 [kworker/1:0H]
root         17  0.0  0.0      0     0 ?        S    17:21   0:00 [watchdog/2]
root         18  0.0  0.0      0     0 ?        S    17:21   0:00 [migration/2]
root         19  0.0  0.0      0     0 ?        S    17:21   0:00 [ksoftirqd/2]
root         21  0.0  0.0      0     0 ?        S<   17:21   0:00 [kworker/2:0H]
root         22  0.0  0.0      0     0 ?        S    17:21   0:00 [watchdog/3]
root         23  0.0  0.0      0     0 ?        S    17:21   0:00 [migration/3]
root         24  0.0  0.0      0     0 ?        S    17:21   0:00 [ksoftirqd/3]
root         26  0.0  0.0      0     0 ?        S<   17:21   0:00 [kworker/3:0H]
====================================================================================================
USER: 启动进程的用户(每一个进程都需要一个特定的用户身份来运行)
PID: 进程运行的ID号
%CPU: 进程占用CPU百分比
%MEM: 进程占用内存百分比
VSZ: 进程占用虚拟内存,(单位KB)
RSS: 进程占用物理内存实际大小(单位KB)
TTY: 运行进程的终端 (?:表示内核进程与终端无关。)
STAT: 进程的状态。(运行 暂停 停止 ……)
START: 启动时间。
TIME: 进程占用CPU的总时间。(0表示还没超过秒)
COMMAND: 进程运行的具体命令。(带有[]的进程表示系统内核的进程。没有带[]的是用户进程。)

STAT状态含义

在这里插入图片描述

基本进程状态:
R:进程运行。
S:可中断进程。
T:进程被暂停。
D:不可中断进程。
Z:僵尸进程。
s:进程是控制进程。
<:进程运行在高优先级上。
N:进程运行在低优先级上。
+:进程在前台运行。
l:多线程进程。
====================================================================================================
常见的进程组合状态:
R+:在前台运行的进程。
Ss:父进程。
S+:进程正在前台运行并且是一个可中断进程。
Ssl:父进程是一个多线程进程。
S<:优先级较高的进程
SN:优先级较低的进程
进程状态切换-范例1
1.在终端1上运行vim
[root@localhost ~]# vim new_file

2.在终端2上运行ps -aux命令查看状态  #S+:进程正在前台运行并且是一个可中断进程。
[root@localhost ~]# ps -aux | grep new_file
root       4157  0.0  0.2 149556  5080 pts/0    S+   18:52   0:00 vim new_file
root       4191  0.0  0.0 112824   980 pts/1    S+   18:53   0:00 grep --color=auto new_file
# 并在终端1上挂起vim,按Ctrl+z

3.回到终端2再次执行ps -aux命令查看状态 #T:进程被暂停。
[root@localhost ~]# ps -aux | grep new_file
root       4157  0.0  0.2 149556  5080 pts/0    T    18:52   0:00 vim new_file
root       4194  0.0  0.0 112824   976 pts/1    S+   18:57   0:00 grep --color=auto new_file

不可中断进程-范例2
- 使用tar打包文件时,可以通过终端不断查看状态,由S+,R+,D+
[root@localhost ~]# tar -czf etc.tar.gz /etc/ /usr/ /var/

[root@localhost ~]# ps aux | grep tar | grep -v grep
root       8401 18.0  0.1 125088  2588 pts/0    R+   18:26   0:07 tar -czf etc.tar.gz /etc/ /usr/ /var/

[root@localhost ~]# ps aux|grep tar|grep -v grep
root       8401 15.3  0.2 126436  4088 pts/0    S+   18:26   0:28 tar -czf etc.tar.gz /etc/ /usr/ /var/

[root@localhost ~]# ps aux|grep tar|grep -v grep
root       8401 15.1  0.2 128272  5568 pts/0    D+   18:26   0:35 tar -czf etc.tar.gz /etc/ /usr/ /var/
僵尸进程-范例3

1.编写C语言程序,然后对该程序进行编译

[root@localhost ~]# cat z.c 
============================================================================================
#include	<sys/types.h>
#include	<sys/wait.h>
#include	<errno.h>
#include	<unistd.h>
#include	<stdlib.h>
#include	<stdio.h>
#include	<string.h>
int	main(int argc, char *argv[])
{
pid_t pid;
pid = fork();
if (pid==0) {
	int iPid =(int)getpid();
	fprintf(stderr,"子进程,%d\n",iPid);
	sleep(1);
	fprintf(stderr,	"Child	exits\n");
	return	EXIT_SUCCESS;
}
int iPid = (int)getpid();
	fprintf(stderr,"父进程,%d\n",iPid);
	fprintf(stderr,	"sleep....\n");
	sleep(360);
	fprintf(stderr,	"parent	exits\n");
	return	EXIT_SUCCESS;
}
============================================================================================

2.编译C语音程序,然后启动进程
[root@localhost ~]# gcc z.c 
[root@localhost ~]# ./a.out 
父进程,8009
sleep....
子进程,8010
Child	exits

3.通过 ps aux查看进程状态
[root@localhost ~]# ps -aux | grep a.out 
root       8052  0.0  0.0   4212   352 pts/0    S+   13:21   0:00 ./a.out
root       8053  0.0  0.0      0     0 pts/0    Z+   13:21   0:00 [a.out] <defunct>
root       8055  0.0  0.0 112824  1004 pts/1    R+   13:21   0:00 grep --color=auto a.out


4.找到僵尸进程的父进程,kill掉父进程,那么僵尸进程将变为孤儿进程,孤儿进程在系统中由init进程接管,init进程将回收杀死进程的资源;或者reboot,因为僵尸进程不会被杀死
#kill僵尸进程(子进程)
[root@localhost ~]# kill 8053
[root@localhost ~]# kill -9 8053
[root@localhost ~]# ps -aux | grep a.out 
root       8052  0.0  0.0   4212   352 pts/0    S+   13:21   0:00 ./a.out
root       8053  0.0  0.0      0     0 pts/0    Z+   13:21   0:00 [a.out] <defunct>

#kill僵尸进程(父进程)
[root@localhost ~]# kill -9 8052
[root@localhost ~]# ps -aux | grep a.out 
root       8059  0.0  0.0 112824  1000 pts/1    R+   13:22   0:00 grep --color=auto a.out

动态查看进程-top

  • 使用top命令查看当前的进程状态
top常用指令
h:查看帮助
1:显示所有CPU的核心的负载
z:以高亮显示数据
b:高亮显示处于R状态的进程
M:按内存使用的百分比排序输出
P:按CPU使用百分比排序输出
q:退出top
每列含义详解
top - 16:00:28 up  3:42,  2 users,  load average: 0.00, 0.01, 0.05
Tasks: 104 total,   2 running, 102 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.3 us,  0.3 sy,  0.0 ni, 99.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1862992 total,  1511664 free,   147820 used,   203508 buff/cache
KiB Swap:  2097148 total,  2097148 free,        0 used.  1526024 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                            8131 root      20   0  162108   2236   1560 R  0.7  0.1   0:00.06 top                                                                
====================================================================================================================
 Tasks: 104 total, 2 running, 102 sleeping, 0 stopped, 0 zombie

一共有个104个进程被运行,1个正在被运行,102个中断的进程,0个被停止的进程,0个僵尸进程
====================================================================================================================
Tasks: 104 total:进程的总数
2 running:正在运行的进程数
102 sleeping:睡眠的进程
0 stopped:停止的进程数
0 zombie僵尸进程数
%Cpu(s):  0.3 us:系统用户进程占用cpu百分比
sy:内核进程占用cpu百分比
ni: 优先级高的进程占用cpu百分比
id:空闲的百分比
wa:等待。这一项数值较大的话说明用户请求磁盘资源,磁盘很慢,请求的资源很多。
hi:硬中断,占的CPU百分比
si:软中断,占的CPU百分比
st:虚拟机占用当前物理服务器的CPU资源的百分比。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

PID:进程id USER:运行进程的用户
PR:进程优先级 NI:负值表示高优先级,正值表示低优先级
VIRT:共享内存 RES:进程使用的、未被换出的物理内存大小
SHR:共享内存大小 S:进程状态
%CPU:占用CPU百分比
%MEM:占用内存百分比
TIME+:进程使用CPU的时间
COMMAND:进程运行的具体命令

如何理解中断

什么是中断?
  • 中断是系统用来响应硬件设备请求的一种机制,它会打断进程的正常调度和执行,然后调用内核中的中断处理程序来响应设备的请求。
为什么要有中断呢?

“举个生活中的例子”

比如说你订了一份外卖,但是不确定外卖什么时候送到,也没有别的方法了解外卖的进度,但是,配送员送外卖是不等人的,到了你这儿没人取的话,就直接走人了。所以你只能苦苦等着,时不时去门口看看外卖送到没,而不能干其他事情。
不过呢,如果在订外卖的时候,你就跟配送员约定好,让他送到后给你打个电话,那你就不用苦苦等待了,就可以去忙别的事情,直到电话一响,接电话、取外卖就可以了。 这里的“打电话”,其实就是一个中断。
没接到电话的时候,你可以做其他的事情;只有接到了电话(也就是发生中断),你才要进行另一个动作:取外卖。
这个例子你就可以发现,中断其实是一种异步的事件处理机制,可以提高系统的并发处理能力。

中断会带来什么问题?

由于中断处理程序会打断其他进程的运行,所以,为了减少对正常进程运行调度的影响,中断处理程序就需要尽可能快地运行。
如果中断本身要做的事情不多,那么处理起来也不会有太大问题;但如果中断要处理的事情很多,中断服务程序就有可能要运行很长时间。
特别是,中断处理程序在响应中断时,还会临时关闭中断。这就会导致上一次中断处理完成之前,其他中断都不能响应,也就是说中断有可能会丢失。

那么还是以取外卖为例:假如你订了 2 份外卖
一份主食和一份饮料,并且是由 2 个不同的配送员来配送。这次你不用时时等待着,两份外卖都约定了电话取外卖的方式。但是,问题又来了。
当第一份外卖送到时,配送员给你打了个很长的电话,商量发票的处理方式。与此同时,第二个配送员也到了,也想给你打电话。
但是很明显,因为电话占线(也就是关闭了中断响应),第二个配送员的电话是打不通的。所以,第二个配送员很可能试几次后就走掉了(也就是丢失了一次中断)。

回到系统中的软中断?

如果你弄清楚了“取外卖”的模式,那对系统的中断机制就很容易理解了。
事实上,为了解决中断处理程序执行过长和中断丢失的问题,Linux 将中断处理过程分成了两个阶段,也就是上半部和下半部:
上半部用来快速处理中断,它在中断禁止模式下运行,主要处理跟硬件紧密相关工作。
下半部用来延迟处理上半部未完成的工作,通常以内核线程的方式运行。

比如说前面取外卖的例子,上半部就是你接听电话,告诉配送员你已经知道了,其他事儿见面再说,然后电话就可以挂断了;下半部才是取外卖的动作,以及见面后商量发票处理的动作。
这样,第一个配送员不会占用你太多时间,当第二个配送员过来时,照样能正常打通你的电话。

除了取外卖,我再举个最常见的网卡接收数据包的例子,让你更好地理解。
网卡接收到数据包后,会通过硬件中断的方式,通知内核有新的数据到了。这时,内核就应该调用中断处理程序来响应它。
对上半部来说,既然是快速处理,其实就是要把网卡的数据读到内存中,然后更新一下硬件寄存器的状态(表示数据已经读好了),最后再发送一个软中断信号,通知下半部做进一步的处理。
而下半部被软中断信号唤醒后,需要从内存中找到网络数据,再按照网络协议栈,对数据进行逐层解析和处理,直到把它送给应用程序。

所以,这两个阶段你也可以这样理解:
上半部直接处理硬件请求,也就是我们常说的硬中断,特点是快速执行;
而下半部则是由内核触发,也就是我们常说的软中断,特点是延迟执行;

中断总结
  • Linux 中的中断处理程序分为上半部和下半部:
    上半部对应硬件中断,用来快速处理中断。
    下半部对应软中断,用来异步处理上半部未完成的工作。
    Linux 中的软中断包括网络收发、定时、调度、等各种类型,可以通过查看 /proc/softirqs 来观察软中断的运行情况。
  • f: 经常听同事说大量的网络小包会导致性能问题,为什么呢?
    q:因为大量的网络小包会导致频繁的硬中断和软中断?所以大量网络小包传输很慢,但如果将网络包一次传递,是不是会快很多呢?

管理进程状态

当程序运行为进程后,如果希望停止进程,那么我们可以使用:kill,pkill,killall

系统支持的信号
  • 1.使用kill -l列出当前系统所支持的信号
[root@localhost ~]# 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常用的3个信号
使用格式:
kill [信号] 进程id

-1 :重新加载配置文件
-9 :强制杀死进程 (谨慎使用)
-15 : 终止进程(默认)

关闭进程kill
  • 使用kill命令,然后指定要杀死的进程PID,即可停止该进程
1.安装vsftpd服务,然后启动
[root@localhost ~]# yum install vsftpd -y
[root@localhost ~]# systemctl start vsftpd
[root@localhost ~]# ps aux | grep vsftpd
root       8413  0.0  0.0  53188   576 ?        Ss   12:06   0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
root       8415  0.0  0.0 112824   988 pts/0    S+   12:07   0:00 grep --color=auto vsftpd

2.发送重载信号,(vsftp的配置文件发生变化,希望重新加载)
[root@localhost ~]# kill -1 8413

3.发送终止进程信号
[root@localhost ~]# kill 8418

4.发送强制终止信号,无法停止服务时,可以用强制终止信号
[root@localhost ~]# kill -9 8413

关闭进程pkill
  • killall,pkill命令用于杀死指定名字的进程
例1:指定服务名称,将其杀死进程
[root@localhost ~]# pkill vsftpd
[root@localhost ~]# killall vsftpd(yum provides killall
查询系统命令来自于哪个软件包)

例2:使用pkill将远程连接用户t下线
[root@localhost ~]# pkill -9 -t pts/0

后台进程管理

什么是后台进程

通常进程都会在终端前台运行,一旦关闭终端,进程也会随着结束,此时希望进程能在后台运行,就是见前台运行的进程放入后台运行,这样就算关闭终端也不影响进程正常运行

为什么需要后台运行

我们在传输大文件时,由于网络的问题需要传输很久,如果此过程中出现网络波动或者关闭终端则会导致传输失败,如果能将传输的进程放入后台,则解决了此类问题

如何将进程转为后台

nohup+&将进程放入后台,然后使用jobs,bg,fg等方式查看进程,但太麻烦了,所以推荐使用screen。

nohup方式
1.使用nohup将前台进程转换后台运行
[root@localhost ~]# nohup sleep 3000 &

2.查看进程运行情况
[root@localhost ~]# ps aux | grep sleep

3.使用job bg fg 等方式查看后台作业
[root@localhost ~]# jobs #查看后台作业
[1]   运行中               nohup sleep 3000 &
[root@localhost ~]# fg %1 #转为前台运行
[root@localhost ~]# bg %1 #转为后台运行
screen方式
1.安装screen工具
screen
管理后台工具。
-list : 查看后台正在运行的命令列表
-r: 进入后台正在运行的某个命令
-S:指定screen窗口名称
进入screen后如果想要回到bash窗口但不终止screen中的任务的话,需要使用ctrl+a+d快捷键实现,如果想终止screen窗口,然后输入exit即可。
[root@localhost ~]# yum install screen -y

2.开启一个screen子窗口,可以通过-S为其指定名称
[root@localhost ~]# vim while.sh
#!
i=0
while true
do
        let i++
        echo "123"
        echo "这是打印的第$i"
        sleep 2
done
========================================================================================================================
[root@localhost ~]# screen -S while_test
 
3.在screen窗口执行任务,可以执行前台运行的任务

4.平滑退出screen ,但不会终止screen中的前台任务
#Ctrl+a+d

5.查看当前由多少screen正在运行
root@localhost ~]# screen -list
There are screens on:
        9030.while_test   (Detached)
1 Sockets in /var/run/screen/S-root.

6.可以通过screenid或screen标签名称进入
[root@localhost ~]# screen -r while_test
[root@localhost ~]# screen -r 9796
[root@localhost ~]# exit		#退出进程,结束screen

进程的优先级

什么是优先级
  • 优先级指的是优先享受资源,优先级的存在主要是解决重要的进程无法可能无法得到更快的执行的问题而产生。例:军人优先
如何为进程配置优先级
  • 在启动进程时,为不同的进程使用不同的调度策略
    • nice值越高,表示优先级越低,最高为+19
    • nice值越低,表示优先级越高,值最低为-20。
    • 一般情况下我们的优先级是0.
如何查看进程优先级

1.使用top命令查看优先级

NI:显示nice值,默认是0
PR:显示nice值,-20映射到0,+19映射到0
PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND  
1083 root	  20	0	298628	2808   1544	S 0.3  0.1		2:49.28	vmtoolsd
5	 root	  0	   -20	0		0		0	S 0.0  0.0		
+0:00.00	kworker/0:+

2.使用ps命令查看进程优先级
[root@localhost ~]# ps axo command,nice | grep sshd | grep -v grep
/usr/sbin/sshd -D             0
sshd: root@pts/1              0   
使用renice修改进程优先级
  • renice命令用于修改一个正在运行的进程优先级
  • 语法格式:renice -n 优先级数字 进程pid
1.查看当前正在运行的sshd进程优先级状态
[root@localhost ~]# ps axo pid,command,nice |grep [s]shd
  7320 /usr/sbin/sshd -D             0
  7853 sshd: root@pts/0              0


2.调整sshd主进程的优先级
[root@localhost ~]# renice -n -20 7320
7320 (进程 ID) 旧优先级为 0,新优先级为 -20

3.调整之后退出终端,重新打开一个新终端
[root@localhost ~]# ps axo pid,command,nice|grep [s]shd
  7320 /usr/sbin/sshd -D           -20
  7853 sshd: root@pts/0              0
  [root@localhost ~]# exit
登出


4.再次登录sshd服务,会由主进程fork子sshd进程(那么子进程会继承主进程的优先级)
[root@localhost ~]# ps axo pid,command,nice|grep [s]shd
  7277 /usr/sbin/sshd -D           -20
  7815 sshd: root@pts/0            -20
使用nice指定程序优先级
  • nice用于指定新启动程序的优先级
    • 语法格式:nice -n 优先级数字 进程名称
1.启动vim并指定程序优先级为 -5
[root@localhost ~]# nice -n -5 vim & 
[1] 7838

2.查看当前vim进程的优先级
[root@localhost ~]# ps axo pid,command,nice | grep 7838
7838 vim                     				-5

进程优先级案例

1.什么是假死

1.所谓假死,就是能ping通,但是ssh不上去;任何其他操作也都没反应,包括上面部署的nginx也打不开页面。

2.假死其实很难出现一次

作为一个多任务操作系统,要把系统忙死,忙到ssh都连不上去,也不是那么容易的。尤其是现在还有fd保护、进程数保护、最大内存保护之类的机制。
你可以fork很多进程,系统会变得很慢,但是ssh还是能连上去;你可以分配很多内存,但是内存多到一定程度oom killer就会把你的进程杀掉,于是ssh又能工作了。

3.假死是如何实现的

有一个确定可以把系统搞成假死的办法是:主进程分配固定内存,然后不停的fork,并且在子进程里面sleep(100)。
也就是说,当主进程不停fork的时候,很快会把系统的物理内存用完,当物理内存不足时候,系统会开始使用swap;那么当swap不足时会触发oom killer进程;
当oom killer杀掉了子进程,主进程会立刻fork新的子进程,并再次导致内存用完,再次触发oom killer进程,于是进入死循环。而且oom killer是系统底层优先级很高的内核线程,也在参与死循环。

4.系统假死为何能ping同无法连接

此时机器可以ping通,但是无法ssh上去。这是由于ping是在系统底层处理的,没有参与进程调度;sshd要参与进程调度,但是优先级没oom killer高,总得不到调度。

5.出现假死怎么办?

为什么要费那么大的力气把机器搞死?我们知道假死是怎么产生的即可,这样可以针对假死的原因进行预防。 (其实假死的情况很少发生,只有当代码写的bug很多的情况下会出现。)
其实建议使用nice将sshd的进程优先级调高。这样当系统内存吃紧,还能勉强登陆sshd,进入调试。然后分析故障。

系统平均负载

  • 每次发现系统变慢时,用top或uptime命令,了解系统的负责情况
[root@localhost ~]# uptime 
 12:36:11 up 18 min,  1 user,  load average: 0.00, 0.01, 0.05
#时间,系统运行时间,正在登录用户数
#最后三个数字依次则是:过去1分钟,5分钟,15分钟的平均负载
什么是平均负载
  • 平均负载是单位时间内,系统处于可运行状态R和不可中断状态D的平均进程数,也就是平均活跃进程数。以2核CPU为例,最合适的平均负载值为2,如果为1说明CPU比较空闲,如果为4,则说明有一半的进程暂时无法被调度。
  • 平均负载与CPU使用率并没有直接关系
可运行状态R
  • 指正在使用CPU或者正在等待CPU的进程,也就是处于R状态到的进程
不可中断状态D
  • 系统中最常见的是等待硬件设备的I/O响应,就是处于D状态的进程,所以,不可中断状态实际是系统对进程和硬件设备的一种保护机制
平均负载合理设定
  • 理想状态:每个cpu上刚好运行这一个进程,这样每个CPU都得到了充分利用
  • 所以在评判平均负载时,先要知道系统有几个CPU,通过top命令获取或/proc/cpuinfo
  • 示例:假设现在有4,2,1,核的CPU,如果平均负载为2时
    • 4核CPU的系统上,意味着CPU有50%的空闲
    • 2核CPU的系统上,意味着CPU刚好被完全占用
    • 1核CPU的系统上,意味着有一半的进程竞争不到CPU
平均负载三大指标
  • 1分钟,5分钟,15分钟的值基本相同,或者相差不大,那说明系统负载很平稳
  • 1分钟的值小于15分钟的值,说明系统最近1分钟的负载在减少,而过去15分钟内却有很大的负载
  • 1分钟的值远大于15分钟的值,就说明最近1分钟的负载在增加,这种增加有可能只是临时性的,也有可能还会持续上升,所以需要持续观察
  • 1分钟的平均负载接近或超过CPU的个数,就意味系统正在发送过载的问题,这就得分析问题,优化解决了
  • 示例:假设有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%)
    • 但从整体趋势来看,系统的负载是在逐步的减低
何时需要关注平均负载
  • 当平均负载高于CPU数量70%的时候,你就应该分析排查负载高的问题了,一旦负载过高,就可能导致进程响应变慢,而影响服务的正常功能
  • 但70%这个数字并不是绝对的,最推荐的方法,还是把系统的平均负载监控起来,然后根据更多的历史数据,判断负载的变化趋势
  • 当发现负载有明显升高趋势时,比如说负载翻倍了,你在去做分析和调查
平均负载案例分析实战
  • 演示三种场景,并用stress,mpstat,pidstat等工具,找出平均负载升高的根源
  • stress是linux系统压力测试工具,这里我们用作异常进程模拟平均负载升高的场景
  • mpstat是多核CPU性能分析工具,用来实时查看每个CPU的性能指标,及CPU的性能指标,及所有CPU的平均指标
  • pidstat是一个常用的进程性能分析工具,用来实时查看进程的CPU,Mem、I/O等性能指标
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
场景1-CPU密集型进程
1.第一个终端运行stress命令,模拟一个CPU使用率100%的场景
[root@localhost ~]# stress -- cpu 1 --timeout 600

2.第二个终端运行uptime查看平均负载的变化情况
#使用watch -d 参数表示高亮显示变化的区域(注意负载会持续升高)
[root@localhost ~]# watch -d uptime
11:25:44	up	2	days,		3:11,		3	users,		load	average:	1.10,	0.30,	0.17
3.在第三个终端运行mpstat查看CPU使用率的变化情况
[root@localhost ~]# mpstat -P ALL 5
#-P ALL表示监控所有CPU,后面5表示间隔5秒后输出一组数据

Linux 3.10.0-1160.49.1.el7.x86_64 (localhost.localdomain) 	2021年12月24日 	_x86_64_	(1 CPU)

11时27分51秒  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
11时27分56秒  all    99.80    0.00    0.20    0.00    0.00    0.00    0.00    0.00    0.00   98.99
11时27分56秒    0    99.80    0.00    0.20    0.00    0.00    0.00    0.00    0.00    0.00   98.99

#单核CPu所以只有一个all和0

4.从终端2可以看到,1分钟的平均负载会慢慢加到1.00,从第三个终端可以看到,正好CpU的使用率为100%,但它的iowait为0,说明平均负载的升高正好由于CPU使用率为100%,到底什么原因导致CPU使用率为100%呢,用pidstat来查询
#间隔5秒后输出一组数据
[root@localhost ~]# pidstat -u 5 1
Linux 3.10.0-1160.49.1.el7.x86_64 (localhost.localdomain) 	2021年12月24日 	_x86_64_	(1 CPU)
11时28分19秒   UID       PID    %usr %system  %guest    %CPU   CPU  Command
11时28分23秒     0      110019    98.80    0.00    0.00    98.80     0  stress

#从这里可以明显看到,stress进程CPU使用率为100%
总结
  • 平均负载提供了一个快速查看系统整体性能的手段,放映了整体的负载情况,但只看平均负载本身,我们并不能直接发现,到底是哪里出现瓶颈,所以,需要注意
  • 平均负载高有可能是CPU密集型进程导致
  • 平均负载高并不代表CPU使用率高,又可能是I/O繁忙
  • 负载高时:使用mpstat,pidstat等工具,辅助分析负载的来源
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿赵的小记录

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值