进程管理(二)
目录
进程的优先级
那么在系统中如何给进程配置优先级
在启动进程时,为不同的进程使用不同的调度策略。
nice值越高:表示优先级越低,例如19,该进程容易将cpu使用量让给其他进程。
nice值越低:表示优先级越高,例如-20,该进程更不倾向于让出cpu。
远程连接不上操作步骤
-
网络
ping 10.0.0.100
-
端口
telnet 10.0.0.150 22 tcping 10.0.0.150 22
-
用户
root
-
密码
1
使用nice命令指定进程优先级
#打开一个终端 [root@zls ~]# nice -n -5 vim zls #打开另一个终端,查看进程的优先级 [root@zls ~]# ps aux|grep [v]im root 2342 0.1 0.2 151720 5212 pts/1 s<+ 19:49 0:00 vim zls [root@zls ~]# ps axo command,nice|grep [v]im vim zls -5
使用renice调整已运行程序的优先级
#先查看sshd的优先级 [root@zls ~]# ps axo pid,command,nice|grep 折叠shd 869 /usr/sbin/sshd -d 0 1194 sshd: root@pts/0 0 1307 sshd: root@pts/1 0 1574 sshd: root@pts/2 0 #设置sshd的优先级为-20 [root@zls ~]# renice -n -20 869 869 (进程 id) 旧优先级为 0,新优先级为 -20 #再次查看sshd的优先级 [root@zls ~]# ps axo pid,command,nice|grep 折叠shd 869 /usr/sbin/sshd -d -20 1194 sshd: root@pts/0 0 1307 sshd: root@pts/1 0 1574 sshd: root@pts/2 0 #一定要退出终端重新连接 [root@zls ~]# exit 登出 #再检查,就可以看到当前终端的优先级变化了 [root@zls ~]# ps axo pid,command,nice|grep sshd 869 /usr/sbin/sshd -d -20 1194 sshd: root@pts/0 0 1574 sshd: root@pts/2 0 2361 sshd: root@pts/1 -20
企业案例,linux假死
什么是假死
所谓假死,就是能ping通,但是ssh不上去;任何其他操作也都没反应,包括上面部署的nginx也打不开页面。
假死如何实现
有一个确定可以把系统搞成假死的办法是:主进程分配固定内存,然后不停的fork,并且在子进程里面sleep(100)。
也就是说,当主进程不停fork的时候,很快会把系统的物理内存用完,当物理内存不足时候,系统会开始使用swap;那么当swap不足时会触发oom killer进程;
当oom killer杀掉了子进程,主进程会立刻fork新的子进程,并再次导致内存用完,再次触发oom killer进程,于是进入死循环。而且oom killer是系统底层优先级很高的内核线程,也在参与死循环。
系统假死为何能ping同无法连接
此时机器可以ping通,但是无法ssh上去。这是由于ping是在系统底层处理的,没有参与进程调度;sshd要参与进程调度,但是优先级没oom killer高,总得不到调度。
怎样解决
其实建议使用nice将sshd的进程优先级调高。这样当系统内存吃紧,还能勉强登陆sshd,进入调试。然后分析故障
后台进程管理
后台进程
通常进程都会在终端前台运行,但是一旦关闭终端,进程也会随着结束,那么此时我们就希望进程能在后台运行,就是将在前台运行的进程放到后台运行,这样即使我们关闭了终端也不影响进程的正常运行。
为什么要把进程放到后台运行
企业中很多时候会有一些需求:
1.传输大文件,由于网络问题需要传输很久
2.我们之前的国外业务,国内到国外,网速很慢,我们需要选择节点做跳板机,那么就必须知道,哪个节点到其他地区网速最快,丢包率最低。
3.有些服务没有启动脚本,那么我们就需要手动运行,并把他们放到后台
后台进程管理
jobs:查看后台进程 bg:永久放到后台 fg:调出后台任务
screen
#安装screen命令 [root@zls ~]# yum install -y screen #安装redis [root@zls ~]# yum install -y redis #启动redis [root@zls ~]# redis-server #放到后台ctrl + z [1]+ 已停止 redis-server #关闭终端,redis进程就没有了 #下载mysql安装包 [root@zls ~]# wget https://downloads.mysql.com/archives/get/file/mysql-5.7.24-linux-glibc2.12-x86_64.tar.gz #使用screen [root@zls ~]# screen -s download_mysqld #ctrl + a + d放置后台 [detached from 3567.download_mysqld] #查看screen列表 [root@zls ~]# screen -list there is a screen on: 3567.download_mysqld (detached) 1 socket in /var/run/screen/s-root. #打开screen终端 [root@zls ~]# screen -r 3567
系统平均负载
每次发现系统变慢时,我们通常做的第一件事,就是执行top或者uptime命令,来了解系统的负载情况。
[root@zls ~]# uptime 20:45:42 up 8:56, 3 users, load average: 0.01, 0.03, 0.05 #我们已经比较熟悉前面几个例子,他们分别是当前时间,系统运行时间,以及正在登陆用户数 #后面三个数依次是:过去1分钟,5分钟,15分钟的平均负载(load average)
平均负载
那到底如何理解平均负载:平均负载是指,单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数
ps:平均负载与cpu使用率并没有直接关系。
可运行状态和不可中断状态是什么?
1.可运行状态进程,是指正在使用cpu或者正在等待cpu的进程,也就是我们用ps命令看的处于r状态的进程
2.不可中断进程,(你在做什么事情的时候是不能被打断的呢?...不可描述)系统中最常见的是等待硬件设备的io相应,也就是我们ps命令中看到的d状态(也成为disk sleep)的进程。
例如:当一个进程向磁盘读写数据时,为了保证数据的一致性,在得到磁盘回复前,他是不能被其他进程或者中断程序打断的,这个是后续的进程就处于不可中断的状态,如果此时进程强制被打断,kill -9 ... perfect准备好护照吧,有多远,走多远,千万别回来了。不可中断状态实际上是系统对进程和硬件设备的一种保护机制
因此,可以简单理解为,平均负载其实就是单位时间内的活跃进程数。
平均负载与cpu的使用率有什么关系
在十几工作中,我们经常容易把平均负载和cpu使用率混淆,所以在这里,我也做一个区分,可能你会感觉到疑惑,既然平均负载代表的是活跃进程数,那平均负载搞了,不就意味着cpu使用率高嘛?
我们还是要回到平均负载的含义上来,平均负载指的是每单位时间内,处于可运行状态和不可中断状态的进程数,所以,它不仅包括了正在使用cpu的进程数,还包括等待cpu和等待io的进程数。
而cpu的使用率是单位时间内,cpu繁忙情况的统计,跟平均浮现在并不一定完全对应。
比如:
cpu密集型进程,使用大量的cpu会导致平均负载升高,此时这两者是一致的。
io密集型进程,等待io也会导致平均负载升高,但cpu使用率不一定很高。
大量等待cpu的进程调度也会导致平均负载升高,此时的cpu使用率也会比较高。
但是cpu的种类也分两种:
cpu密集型
io密集型
例如mysql服务器,就需要尽量选择使用io密集型cpu
平均负载案例分析实战
下面我们以三个示例分别来看这三中情况,并用:stress、mpstat、pidstat等工具找出平均负载升高的根源
stress
是linux系统压力测试工具,这里我们用作异常进程模拟平均负载升高的场景。
mpstat
是多核cpu性能分析工具,用来实时检查每个cpu的性能指标,以及所有cpu的平均指标。
pidstat
是一个常用的进程性能分析工具,用来实时查看进程的cpu,内存,io,以及上下文切换等性能指标。
#安装stress,命令sysstat yum provides strees #找寻安装包 [root@zls ~]# yum install -y stress [root@zls ~]# yum install -y sysstat
案例一:cpu密集型
我们在第一个中断运行stress命令,模拟一个cpu使用率100%的场景:
#第一个终端执行 [root@zls ~]# stress --cpu 1 --timeout 600 #第二个终端查看 [root@zls ~]# uptime 22:04:12 up 10:15, 4 users, load average: 1.98, 0.57, 0.22 #高亮显示变化区域 [root@zls ~]# watch -d uptime every 2.0s: uptime sun jul 14 22:05:16 2019 22:05:16 up 10:16, 4 users, load average: 2.84, 1.05, 0.41
使用mpstat查看cpu使用率的变化情况
[root@zls ~]# mpstat -p all 5 linux 3.10.0-862.el7.x86_64 (zls) 2019年07月14日 _x86_64_ (1 cpu) 22时08分51秒 cpu %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 22时08分56秒 all 99.20 0.00 0.80 0.00 0.00 0.00 0.00 0.00 0.00 0.00 22时08分56秒 0 99.20 0.00 0.80 0.00 0.00 0.00 0.00 0.00 0.00 0.00 22时08分56秒 cpu %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 22时09分01秒 all 99.60 0.00 0.40 0.00 0.00 0.00 0.00 0.00 0.00 0.00 22时09分01秒 0 99.60 0.00 0.40 0.00 0.00 0.00 0.00 0.00 0.00 0.00
从终端2可以看到,1分钟平均负载会慢慢增加到2.00,而从终端三中还可以看到,正好有一个cpu的使用率为100%,但他的iowait只有0,这说明平均负载的升高正式由于cpu使用率为100%,那么到底哪个进程导致cpu使用率为100%呢?可以使用pidstat来查询
#间隔5秒输出一组数据 [root@zls ~]# pidstat -u 5 1 linux 3.10.0-862.el7.x86_64 (zls) 2019年07月14日 _x86_64_ (1 cpu) 22时14分00秒 uid pid %usr %system %guest %cpu cpu command 22时14分05秒 0 8349 0.00 0.20 0.00 0.20 0 kworker/0:3 22时14分05秒 0 9903 99.60 0.00 0.00 99.60 0 stress 平均时间: uid pid %usr %system %guest %cpu cpu command 平均时间: 0 8349 0.00 0.20 0.00 0.20 - kworker/0:3 平均时间: 0 9903 99.60 0.00 0.00 99.60 - stress
案例二:i/o密集型
还是使用stress命令,但是这次模拟io的压力
[root@zls ~]# stress --io 1 --timeout 600s
在第二个终端运行uptime查看平均负载的变化情况
[root@zls ~]# watch -d uptime every 2.0s: uptime sun jul 14 22:17:38 2019 22:17:38 up 10:28, 4 users, load average: 2.47, 2.25, 1.61
在第三个终端运行mpstat查看cpu使用率的变化情况
[root@zls ~]# mpstat -p all 5 linux 3.10.0-862.el7.x86_64 (zls) 2019年07月14日 _x86_64_ (1 cpu) 22时19分32秒 cpu %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 22时19分37秒 all 2.78 0.00 97.22 0.00 0.00 0.00 0.00 0.00 0.00 0.00 22时19分37秒 0 2.78 0.00 97.22 0.00 0.00 0.00 0.00 0.00 0.00 0.00 22时19分37秒 cpu %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 22时19分42秒 all 3.01 0.00 96.99 0.00 0.00 0.00 0.00 0.00 0.00 0.00 22时19分42秒 0 3.01 0.00 96.99 0.00 0.00 0.00 0.00 0.00 0.00 0.00 #发现cpu与内核打交道的sys占用非常高
那么到底哪个进程导致iowait这么高呢?
[root@zls ~]# pidstat -u 5 1 linux 3.10.0-862.el7.x86_64 (zls) 2019年07月14日 _x86_64_ (1 cpu) 22时20分59秒 uid pid %usr %system %guest %cpu cpu command 22时21分04秒 0 6900 0.00 0.20 0.00 0.20 0 kworker/0:0 22时21分04秒 0 10104 2.76 83.07 0.00 85.83 0 stress 22时21分04秒 0 10105 0.00 10.63 0.00 10.63 0 kworker/u256:2 平均时间: uid pid %usr %system %guest %cpu cpu command 平均时间: 0 6900 0.00 0.20 0.00 0.20 - kworker/0:0 平均时间: 0 10104 2.76 83.07 0.00 85.83 - stress 平均时间: 0 10105 0.00 10.63 0.00 10.63 - kworker/u256:2
这时候发现看到的数据比较少,需要更新一下命令:
#下载新版本的包 [root@zls ~]# wget http://pagesperso-orange.fr/sebastien.godard/sysstat-11.7.3-1.x86_64.rpm #升级到新版本 [root@zls ~]# rpm -uvh sysstat-11.7.3-1.x86_64.rpm 准备中... ################################# [100%] 正在升级/安装... 1:sysstat-11.7.3-1 ################################# [ 50%] 正在清理/删除... 2:sysstat-10.1.5-17.el7 ################################# [100%]
然后再次查看结果,明显显示的数据多了
[root@zls ~]# pidstat -u 5 1 linux 3.10.0-862.el7.x86_64 (zls) 2019年07月14日 _x86_64_ (1 cpu) 22时24分40秒 uid pid %usr %system %guest %wait %cpu cpu command 22时24分45秒 0 281 0.00 0.20 0.00 0.40 0.20 0 xfsaild/sda3 22时24分45秒 0 10104 2.99 82.67 0.00 0.00 85.66 0 stress 22时24分45秒 0 10105 0.00 8.76 0.00 92.43 8.76 0 kworker/u256:2 22时24分45秒 0 10118 0.20 0.40 0.00 0.00 0.60 0 watch 22时24分45秒 0 10439 0.00 3.98 0.00 94.82 3.98 0 kworker/u256:3 22时24分45秒 0 11007 0.00 0.20 0.00 0.00 0.20 0 pidstat 平均时间: uid pid %usr %system %guest %wait %cpu cpu command 平均时间: 0 281 0.00 0.20 0.00 0.40 0.20 - xfsaild/sda3 平均时间: 0 10104 2.99 82.67 0.00 0.00 85.66 - stress 平均时间: 0 10105 0.00 8.76 0.00 92.43 8.76 - kworker/u256:2 平均时间: 0 10118 0.20 0.40 0.00 0.00 0.60 - watch 平均时间: 0 10439 0.00 3.98 0.00 94.82 3.98 - kworker/u256:3 平均时间: 0 11007 0.00 0.20 0.00 0.00 0.20 - pidstat
案例三:大量进程的场景
当系统运行进程超出cpu运行能力时,就会出现等待cpu的进程。
1.首先,我们还是使用stress命令,模拟的是多个进程
[root@zls ~]# stress -c 4 --timeout 600
2.由于系统只有一个cpu,明显比4个进程要少的多。因此,系统的cpu处于严重过载状态
[root@zls ~]# every 2.0s: uptime sun jul 14 22:28:50 2019 22:28:50 up 10:39, 4 users, load average: 3.96, 3.89, 3.00
3.在运行pidstat命令来查看一下进程的情况
[root@zls ~]# pidstat -u 5 1 linux 3.10.0-862.el7.x86_64 (zls) 2019年07月14日 _x86_64_ (1 cpu) 22时31分12秒 uid pid %usr %system %guest %wait %cpu cpu command 22时31分17秒 0 11317 24.75 0.00 0.00 75.05 24.75 0 stress 22时31分17秒 0 11318 24.95 0.00 0.00 75.45 24.95 0 stress 22时31分17秒 0 11319 24.75 0.00 0.00 75.25 24.75 0 stress 22时31分17秒 0 11320 24.75 0.00 0.00 75.45 24.75 0 stress 22时31分17秒 0 11381 0.20 0.40 0.00 0.00 0.60 0 watch 22时31分17秒 0 11665 0.00 0.20 0.00 0.00 0.20 0 pidstat 平均时间: uid pid %usr %system %guest %wait %cpu cpu command 平均时间: 0 11317 24.75 0.00 0.00 75.05 24.75 - stress 平均时间: 0 11318 24.95 0.00 0.00 75.45 24.95 - stress 平均时间: 0 11319 24.75 0.00 0.00 75.25 24.75 - stress 平均时间: 0 11320 24.75 0.00 0.00 75.45 24.75 - stress 平均时间: 0 11381 0.20 0.40 0.00 0.00 0.60 - watch 平均时间: 0 11665 0.00 0.20 0.00 0.00 0.20 - pidstat
总结
1.平均负载高有可能是cpu密集型进程导致的
2.平均负载高并不一定代表cpu的使用率就一定高,还有可能是i/o繁忙
3.当发现负载高时,可以使用mpstat、pidstat等工具,快速定位到,负载高的原因,从而做出处理