在上面出现CPU使用率高的时候,记住,当碰到无法解释的CPU使用率的时候,要首先检查是不是有短时进程在捣鬼
CPU使用率的类型,除了之前说的用户CPU之外,还包括系统CPU,等待IO的CPU 中断CPU等
那么我们我们就说一下常见的服务器性能问题
进程状态
在iowait升高的时候,进程可能因为得不到硬件的响应,长时间处于不可中断状态,导致从ps或者top中查看的时候,都处于D状态,即为不可中断
那么除了D状态,还有哪些状态,这需要我们进行有一次总结
top和ps是最常见的进程状态工具,从top输出开始看,S是stauts表示进程的状态,其中常见的状态有 R D Z S I 几个状态,分别是什么意思?
基本如下,对应的意思有哪些呢?
对应的如下
R是Running或者Runnable的缩写,说明在CPU的就绪队列中,正在运行或者等待运行你
D是Disk Sleep,不可中断睡眠,进程正在和硬件交互
Z是Zombie的缩写 僵尸进程,等待父进程回收资源
S是Interruptible Sleep 可中断状态睡眠,表示进程因为等待某个事件被系统挂起,当进程等待的事件发生的时候,会进入R状态
I是Idle的缩写,空闲状态,在不可中断睡眠的内核线程上,硬件交互导致的不可中断进程用D表示,可能是没有任何的负载线程,但是I的线程不会导致平均负载升高
除此外,还可能有一下两个状态
第一个是T或者t是Stopped或者Traced的缩写,表示进程处于暂停或者追踪状态
SIGSTOP信号会将一个进程变为暂停状态,如果在发送SIGCONT信号,就会恢复运行
如果使用gdb调试一个进程的时候,进程就会变为跟踪状态,就是一种特殊的暂停
最后就是X,Dead的缩写,说明进程已经死亡
那么对于上面的状态,常见的话,不可中断状态是很少见的,因为一般硬件的使用很短时间内就会结束
如果系统或者硬件出现了故障,进程才可能会在不可中断状态,这时候就需要判断系统是不是出现了IO等性能问题
僵尸进程,也是多进程应用常见的问题,就是一个进程创建了子进程,会通过系统调用wait或者waitpid等待子进程结束,回收子进程的资源,子进程结束后,会向父进程发送SIGCHLD信号,所以,父进程还可以注册SIGCHLD的信号处理函数,异步回收资源
但是父进程如果没有回收,就会导致子进程变为僵尸进城,但一般僵尸进程的时间都比较短,父进程回收资源后僵尸进程就会消亡,父进程退出后,init进程也会回收后消亡
如果存在大量的子进程处于僵尸状态,那么会用尽PID进程号,导致新进程不能创建
接下来是一个案例
我们新引入一个工具dstat,整合了vmstat iostat ifstat等几种工具的优点,同时观察系统的CPU,磁盘IO 网络 及 内存使用情况
接下来我们打开一个终端,登录到机器上
然后运行对应的案例应用
运行案例应用后,如果一切正常,可以看到对应的输出
$ ps aux | grep /app
root 4009 0.0 0.0 4376 1008 pts/0 Ss+ 05:51 0:00 /app root 4287 0.6 0.4 37280 33660 pts/0 D+ 05:54 0:00 /app root 4288 0.6 0.4 37280 33668 pts/0 D+ 05:54 0:00 /app |
看到了对应的进程状态为Ss+和D+,S表示可中断睡眠,D表示不可中断睡眠,后面的s和+分别说明是会话的领导进程,前台进程组
进程组表示一组相互关联的进程,每个子进程都是父进程所在组的成员
会话则是共享同一个终端的一个或者多个进程组
比如,我们通过SSH登录服务器,打开一个TTY终端,终端就对应的一个回话,终端内运行的命令,就构成了一个个的进程组,其中,后台运行的,就构成了后台运行组,前台运行的,就是前台进程组
我们看一下top资源的使用情况
上面可以看出,平均负载在 1 5 15 分钟内逐渐减小,负载在升高,说明系统可能达到了性能瓶颈
但是Tasks中有一个运行中进程,其他全是僵尸进程,说明子进程退出时候没有清理
接下来是每个进程的情况,CPU使用率最高的进程只有0.3%,但是还有两个进程处于D状态,说明可能在等待I/O,并不能确定是其导致了iowait升高
其次iowait太高,导致系统平均负载升高了
其次僵尸进程不断增加,说明有程序没有正确的清理子进程的资源
那么,总结一下
我们通过简单的操作,熟悉了几个必备的进程状态,常见状态包括了
运行 R 空闲 I 不可中断睡眠 D 可中断睡眠 S 僵尸 Z 暂停 T
不可中断状态和僵尸状态是本章着重讲解的
不可中断状态表示进程正在和硬件交互,为了保护数据和硬件的一致性
系统不允许其他进程打断这个进程,进程长时间处于不可中断状态,说明系统可能有IO性能问题
僵尸进程的出现,说明父进程没有合理的回收子进程占有的资源,短暂的僵尸状态没有问题,但是长时间处于僵尸状态,就需要注意应用程序有没有正常处理子进程退出