一、进程的类型
在Linux中有守护(daemon)进程,在后台运行;还有一种在前台运行的进程,那么这种进程会阻塞此终端,做不了别的事情了,但是此类进行可以使用类似supervisor这样的工具来进行维护。而Linux中的守护进程也分为两种:独立守护进程和瞬时守护进程。
独立守护进程:chkconfig可以控制关联运行级别的服务,这种进程又两大特点:一是可以自行启动运行而不需要利用系统其他机制来管理,二是启动之后会一直占用系统内存与系统资源。因而这种守护进程有一个非常突出的优点响应最快。这种进程在Linux中也非常多;如apache、mysql等。
超级守护进程xinetd:管理瞬时守护进程相当于代理人不需要关联至运行级别和不需要实时守护当有其他进程来访问时由超级守护进程来通知瞬时守护进程并唤醒;特点跟独立守护相反。
xinetd守护进程的配置文件放置在/etc/xinetd.d/目录下和/etc/xinetd.conf文件中。一般不用关心xinetd.conf文件的内容。而/etc/xinetd.d中的每个文件代表一个独立的xinetd守护进程。
安装xinetd
1 2 |
$ yum –y install xinetd $ service xinetd start |
瞬时守护进程
1 2 |
$ yum -y install telnet $ chkconfig telnet on|off |
二、进程管理命令
ps
显示静态进程信息(BSD风格)
1 2 3 4 |
$ ps aux a:显示所有跟终端有关的进程; u:显示进程的开启用户; x:显示跟终端无关的进程; |
1 2 3 |
$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 2172 664 ? Ss Jul15 0:07 init [3] |
进程的基本属性解释:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
USER #运行这个进程的用户; PID #进程的PID号; %CPU #占用CPU的百分比; %MEM #占用内存的百分比; VSZ #虚拟内存集,常驻内存集位于物理内存当中且不能被交换出去的; RSS #常驻内存集,虚拟内存集在逻辑视图上看占据的大小包括memory mapped region for shared libraries调用的共享库; STAT #进程状态有如下; D #不可中断的睡眠 R #运行或就绪; S #可中断的睡眠; T #停止的进程; Z #僵死的进程; S #会话进程首进程; < #高优先级进程; N #低优先级进程; + #前台进程组中的进程,1多线程进程; START TIME #开始的日期和时间; COMMAND #这个进程执行的命令; |
ps
显示静态进程信息(SysV风格)
1 2 3 |
$ ps -elf F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD 4 S root 1 0 0 75 0 - 543 - Jul15 ? 00:00:07 init [3] |
对于SysV风格的ps选项可以发现多了一个PPID字段,就是用于显示此进行的父进程的PID,在排查进程问题的时候还是很有用的。
另外,ps可以显示给定进程的相关线程:
1 |
$ ps -T -p 6374 |
top
显示动态系统进程活动状态以及一些系统状况信息,top作为日常管理工作中最常用也是最重要的Linux系统监控工具之一,可以动态观察系统进程状况。top命令显示的项目很多,默认值是每5秒更新一次。
1 |
$ top [OPTIONS] |
常用选项
1 2 3 4 5 6 7 8 9 10 11 12 13 |
-b : 批次模式运行; -c : 显示执行任务的命令行信息,就可以知道这个进程是那个命令运行的; -d : 设定延迟时间,默认5秒刷新一次,如10秒刷新一次,top -d 10; -H : 显示线程。将显示所有进程产生的线程; -i : 显示空闲的进程; -n : 执行次数,一般与-b搭配使用; -u : 监控指定用户相关进程; -U : 监控指定用户相关进程; -p : 监控指定的进程; -s : 安全模式操作; -S : 累计时间模式; -v : 显示top版本,然后退出; -M : 自动显示内存单位(k/M/G); |
使用示例
1 |
$ top -d 10 |
第1行信息(top)
1 2 3 4 |
13:31:56 #当前时间; up 3:34 #系统运行时间,格式为时:分; 1 user #当前登录用户数; load average: 1.76, 1.98, 2.14 #系统负载,即任务队列的平均长度;三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值; |
第2行信息(Tasks)
1 2 3 4 5 |
Tasks: 686 total #进程总数量; 2 running #正在运行的进程数; 684 sleeping #睡眠的进程数; 0 stopped #停止的进程数; 0 zombie #僵尸进程数; |
第3-10行信息(Cpu0)
1 2 3 4 5 6 7 8 |
11.3% us #用户空间占用CPU百分比; 1.7% sy #内核空间占用CPU百分比; 0.0% ni #用户进程空间内改变过优先级的进程占用CPU百分比; 83.7% id #空闲CPU百分比; 0.0% wa #等待输入输出的CPU时间百分比 0.0% hi #此CPU正在处理硬中断的百分比; 3.1% si #此CPU正在处理软中断的百分比; 0.0% st #被偷走的时间百分比; |
第11行信息(KiB Mem)
1 2 3 4 5 |
8197212 total #物理内存总量; 4770840 used #使用的物理内存总量; 3426372 free #剩余的物理内存总量; 35836 buffers #物理内存缓冲区占用的内存大小; 1276688 cached Mem #物理内存缓存区占用的内存大小; |
第12行信息(KiB Swap)
1 2 3 |
5213180 total #Swap交换分区的容量; 0 used #Swap交换分区使用的容量 5213180 free #Swap交换分区剩余的容量; |
第13行信息(KiB Swap)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
PID #进程ID号; USER #进程所有者; PR #进程的优先级别、越小越被优先执行; NI #nice值; VIRT #进程占用的虚拟内存; RES #进程占用的共享内存; S #进程的状态; %CPU #进程占用CPU的使用率; %MEM #进程占用内存的使用率(物理内存); TIME+ #该进程启动后占用总的CPU时间; CMD #命令名称; |
top常用的命令
1 2 3 4 5 6 7 |
1 #显示CPU核数,默认是不显示内核核心数; M #根据驻留内存排序; P #根据CPU占用排序; T #根据累计时间进行排序; H #显示线程; q #退出; k #杀死进程; |
查问题的大招,多种条件合并显示,-p指定进程号,-d每10秒刷新一次,-c显示指令完整命令,-H显示相关线程。
1 |
$ top -d 10 -c -H -p 65574 |
uptime:系统简单信息输出(同top命令第一行)
1 2 |
$ uptime 15:09:51 up 48 days, 2 min, 1 user, load average: 0.00, 0.05, 0.07 |
pstree
以树状结构显示进程,并显示进程号。
1 |
$ pstree -p |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$ pstree init─┬─AliHids───8*[{AliHids}] ├─AliYunDun───8*[{AliYunDun}] ├─AliYunDunUpdate───6*[{AliYunDunUpdat}] ├─gshelld───3*[{gshelld}] ├─login───bash ├─5*[mingetty] ├─mysqld_safe───mysqld───15*[{mysqld}] ├─nginx───nginx ├─nscd───7*[{nscd}] ├─ntpd ├─php-fpm───10*[php-fpm] ├─rsyslogd───3*[{rsyslogd}] ├─sshd───sshd───bash───pstree ├─udevd───2*[udevd] └─xinetd |
pgrep
以名称为依据从运行进程队列中查找进程,并显示查找到的进程id。每一个进程ID以一个十进制数表示,通过一个分割字符串和下一个ID分开,默认的分割字符串是一个新行。对于每个属性选项,用户可以在命令行上指定一个以逗号分割的可能值的集合。
1 2 3 4 5 6 7 8 |
$ pgrep [options] [argument] -o:仅显示找到的最小(起始)进程号; -n:仅显示找到的最大(结束)进程号; -l:显示进程名称和PID; -P:指定父进程号; -g:指定进程组; -t:指定开启进程的终端; -u:指定进程的有效用户ID; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 根据进程名显示进程号; $ pgrep -l httpd 4557 httpd 4560 httpd 4561 httpd # 根据进程名显示进程名和PID; $ pgrep httpd 4557 4560 4561 # 根据用户名显示进程号和进程名; $ pgrep –l -u root |
kill
终止一个进程
1 2 3 |
$ kill [options] PID -9 #强制杀死进程; all #终止指定的所有进程; |
Linux中的重要信号
1=SIGHUP :让一个进程不用重启就可以重读其配置文件并让新的配置信息生效;
2=SIGINT :中断一个进程;
9=SIGKILL :强制杀死一个进程;
15=SIGTERM :终止一个进程,默认信号;
pidof
根据进程名查找其PID号
1 2 |
$ pidof init 1 |
&
把作业启动时直接送到后台执行
1 2 |
$ cp -fr /boot/ /root/ & [1] 81241 |
Ctrl+z
把已经启动的作业送到后台,进程在后台默认为停止状态
1 2 3 |
$ cp -fr /etc/ /boot/ ^Z [1]+ Stopped cp -i -fr /etc/ /boot/ |
jobs
查看后台的作业(作业号不同于进程号)
1 2 |
$ jobs [1]+ Stopped cp -i -fr /etc/ /boot/ |
bg
把后台停止的作业运行起来
1 2 3 4 5 6 |
$ jobs [1]+ Stopped cp -i -fr /etc/ /boot/ $ bg 1 [1]+ cp -i -fr /etc/ /boot/ & $ jobs [1]+ Running cp -i -fr /etc/ /boot/ & |
fg
把后台的作业调到前台执行
1 2 |
$ fg 1 cp -i -fr /etc/ /boot/ |
kill %JOB_ID
终止后台作业,%不能省略不然就成了终止进程
1 |
$ kill %1 |
pmap
查看进程占用的内存空间
1 |
$ pmap -d 1 |
也可以使用cat /proc/1/maps查看1号进程占据内存的空间,每个进程都有。
vmstat
查看系统状态、CPU使用率、内存、IO等情况
1 2 3 4 5 |
$ vmstat 2 1 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------ r b swpd free buff cache si so bi bo in cs us sy id wa st 0 0 68 152708 148424 3362524 0 0 0 33 1 1 0 0 97 2 0 (2表示每个两秒采集一次服务器状态,1表示只采集一次) |
procs段
1 2 |
r:表示运行队列(就是说多少个进程真的分配到CPU) ; b:进程阻塞; |
memory段
1 2 3 4 |
swpd:虚拟内存已使用的大小; free:空闲的物理内容; buff:缓冲占用大小用来存储inode、权限等信息; cache:缓存占用大小直接用来记忆我们打开的文件,给文件做缓存; |
swap段
1 2 |
si:每秒从磁盘读入虚拟内存的大小; so:每秒虚拟内存写入磁盘的大小; |
io段
1 2 |
bi:块设备每秒接收的块数量; bo:块设备每秒发送的块数量; |
System段
1 |
in:每秒CPU的中断次数,包括时间中断; |
Cpu段
1 2 3 4 5 |
cs:每秒上下文切换次数,例如我们调用系统函数,就要进行上下文切换,线程的切换,也要进程上下文切换;这个值要越小越好,太大了,要考虑调低线程或者进程的数目; us:用户CPU时间; sy:系统CPU时间,如果太高,表示系统调用时间长; id:空闲 CPU时间; wt:等待IO CPU时间; |
iostat
查看CPU负载,硬盘状况
1 2 3 4 5 6 7 8 9 |
$ iostat 2 1 Linux 2.6.32-431.el6.x86_64 (localhost.localdomain) 2015年04月01日 _x86_64_ (1 CPU) avg-cpu: %user %nice %system %iowait %steal %idle 0.04 0.07 0.34 0.32 0.00 99.22 Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn sda 1.19 35.80 24.64 2595400 1786172 scd0 0.00 0.01 0.00 404 0 dm-0 4.16 35.21 24.64 2552394 1786096 dm-1 0.00 0.04 0.00 2576 0 |
avg-cpu段意义
1 2 3 4 5 6 7 8 9 |
%user #在用户级别运行所使用的CPU的百分比; %nice #nice操作所使用的CPU的百分比; %sys #在系统级别(kernel)运行所使用CPU的百分比; %iowait #CPU等待硬件I/O时,所占用CPU百分比; %idle #CPU空闲时间的百分比; |
Device段意义
1 2 3 4 5 |
Tps #每秒钟发送到的IO请求数; Blk_read/s #每秒读入的数据块; Blk_wrtn/s #每秒写入的数据块; Blk_read #一共读入的数据块; Blk_wrtn #一共写入的数据块; |
dstat
使用Python编写的dstat实时查看命令是一个可以取代vmstat,iostat,netstat,ifstat这些命令的多功能产品;dstat克服了这些命令的局限并增加了一些另外的功能,增加了监控项也变的更加灵活了;dstat可以很方便监控系统运行的状况并用于基准测试和排除故障。
1 2 3 4 5 6 7 8 9 10 11 12 |
$ dstat ----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system-- usr sys idl wai hiq siq| read writ| recv send| in out | int csw 0 0 99 0 0 0| 19k 13k| 0 0 | 0 0 | 18 20 0 0 99 1 0 0| 0 0 | 60B 826B| 0 0 | 24 21 (默认1秒刷新一次一直显示结果,dstat 3 10:表示报表输出间隔时间3秒;一种输出10个结果) total-cpu-usage #显示CPU信息; dsk/total #显示磁盘读写总数; net/total #网络设备发送和接收的棕数据; paging #内存分页换进换出数; system #中断int和上下文切换csw数; |
可带的选项
1 2 3 4 5 6 7 |
-l #显示负载统计量; -m #显示内存使用率; -s #显示交换分区使用情况; -fs #显示文件系统统计数据; -tcp #显示常用的tcp统计; -udp #显示常用的udp; --nocolor #不显示颜色; |
dstat附带了一些插件很大程度地扩展了它的功能可通过/usr/share/dstat/目录查看
1 2 3 4 5 6 7 |
--disk-util #显示某一时间磁盘的忙碌状况; --freespace #显示当前磁盘空间使用详细情况; --proc-count #显示正在运行的程序数量; --top-bio #指出块I/O最大的进程; --top-cpu #图形化显示CPU占用最大的进程; --top-io #显示正常I/O最大的进程; --top-mem #显示占用最多内存的进程; |
htop
比top更高级的进程监控工具
F1:显示帮助信息以便使用Htop
F2:进入htop的设定界面;可以根据自己的使用习惯和风格定制化
F3:htop提供的搜索功能;输入进程名即可
F4:进入过滤器、相当于关键字搜索且不区分大小写
F5:显示树状结构
F6:选择排序方式;最常用的就是cpu和memory
F7:htop提供的nice-;选定一个进程直接可以调整nice值
F8:htop提供的nice+;选定一个进程直接可以调整nice值
F9:结束进程
安装htop
1 2 3 4 5 |
[root@localhost ~]# yum install ncurses-devel [root@localhost ~]# tar zxvf htop-1.0.2.tar.gz [root@localhost ~]# cd htop-1.0.2 [root@localhost ~]# ./configure [root@localhost ~]# make && make install |
三、守护进程控制命令”chkconfig”
chkconfig命令是CentOS 7之前系统使用的服务控制命令,在CentOS 7系统中开始使用systemd init管理服务了,所以此命令已经没用了。
1 2 3 4 5 6 |
chkconfig -list #查看系统上所有独立守护进程并显示对应级别下的默认状态; chkconfig -list SERVICE_NAME #查看某一个进程服务; chkconfig -level 234 SERVICE_NAME on|off #开启或关闭对应级别下的状态; chkconfig SERVICE_NAME on|off #开启或关闭服务不指定默认2345级别; chkconfig -add SERVICE_NAME #添加服务并在rc#.d下创建K或S开头的链接文件; chkconfig -del SERVICE_NAME #删除rc#.d下创建以K或S开头的链接文件; |
四、CPU利用率和负载率的区别
这里要区别CPU负载和CPU利用率,它们是不同的两个概念,但它们的信息可以在同一个top命令中进行显示。CPU利用率显示的是程序在运行期间实时占用的CPU百分比,这是对一个时间段内CPU使用状况的统计,通过这个指标可以看出在某一个时间段内CPU被占用的情况, 如果被占用时间很高,那么就需要考虑CPU是否已经处于超负荷运作。而CPU负载显示的是在一段时间内CPU正在处理以及等待CPU处理的进程数之和的统计信息,也就是CPU使用队列的长度的统计信息。
CPU利用率高并不意味着负载就一定大,可能这个任务是一个CPU密集型的。一样CPU低利用率的情况下是否会有高Load Average的情况产生呢?理解占有时间和使用时间就可以知道,当CPU分配时间片以后,是否使用完全取决于使用者,因此完全可能出现低利用率高Load Average的情况。另外IO设备也可能导致CPU负载高。
由此来看,仅仅从CPU的使用率来判断CPU是否处于一种超负荷的工作状态还是不够的,必须结合Load Average来全局的看CPU的使用情况。网上有个例子来说明两者的区别如下:某公用电话亭,有一个人在打电话,四个人在等待,每人限定使用电话一分钟,若有人一分钟之内没有打完电话,只能挂掉电话去排队,等待下一轮。电话在这里就相当于CPU,而正在或等待打电话的人就相当于任务数。在电话亭使用过程中,肯定会有人打完电话走掉,有人没有打完电话而选择重新排队,更会有新增的人在这儿排队,这个人数的变化就相当于任务数的增减。为了统计平均负载情况,我们5秒钟统计一次人数,并在第1、5、15分钟的时候对统计情况取平均值,从而形成第1、5、15分钟的平均负载。有的人拿起电话就打,一直打完1分钟,而有的人可能前三十秒在找电话号码,或者在犹豫要不要打,后三十秒才真正在打电话。如果把电话看作CPU,人数看作任务,我们就说前一个人(任务)的CPU利用率高,后一个人(任务)的CPU利用率低。当然, CPU并不会在前三十秒工作,后三十秒歇着,CPU是一直在工作。只是说,有的程序涉及到大量的计算,所以CPU利用率就高,而有的程序牵涉到计算的部分很少,CPU利用率自然就低。但无论CPU的利用率是高是低,跟后面有多少任务在排队没有必然关系。
CPU数量和CPU核心数(即内核数)都会影响到CPU负载,因为任务最终是要分配到CPU核心去处理的。两块CPU要比一块CPU好,双核要比单核好。因此,我们需要记住,除去CPU性能上的差异,CPU负载是基于内核数来计算的,即“有多少内核,即有多少负载”,如单核最好不要超过100%,也就是负载为1.00,如此类推。
Linux里有一个/proc目录,存放的是当前运行系统的虚拟映射,其中有一个文件为cpuinfo,这个文件里存放着CPU的信息。/proc/cpuinfo文件按逻辑CPU而非真实CPU分段落显示信息,每个逻辑CPU的信息占用一个段落,第一个逻辑CPU标识从0开始。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
$ cat /proc/cpuinfo processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 63 model name : Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz stepping : 2 microcode : 0x36 cpu MHz : 2399.998 cache size : 20480 KB physical id : 0 siblings : 2 core id : 0 cpu cores : 2 apicid : 0 initial apicid : 0 fpu : yes fpu_exception : yes cpuid level : 15 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr ...... bogomips : 4799.99 clflush size : 64 cache_alignment : 64 address sizes : 42 bits physical, 48 bits virtual power management: |
要理解该文件中的CPU信息,有几个相关的概念要知道,如:processor表示逻辑CPU的标识、model name表示真实CPU的型号信息、physical id表示真实CPU和标识、cpu cores表示真实CPU的内核数等等。
逻辑CPU的描述:现在的服务器一般都使用了“超线程”(Hyper-Threading,简称HT)技术来提高CPU的性能。超线程技术是在一颗CPU同时执行多个程序而共同分享一颗CPU内的资源,理论上要像两颗CPU一样在同一时间执行两个线程。虽然采用超线程技术能同时执行两个线程,但它并不象两个真正的CPU那样,每各CPU都具有独立的资源。当两个线程都同时需要某一个资源时,其中一个要暂时停止,并让出资源,直到这些资源闲置后才能继续。因此超线程的性能并不等于两颗CPU的性能。具有超线程技术的CPU还有一些其它方面的限制。
五、CPU负载率的计算方式
Load average的概念源自UNIX系统,虽然各家的公式不尽相同,但都是用于衡量正在使用CPU的进行数量和正在等待CPU的进程数量,一句话就是runable processes的数量。所以Load average可以作为CPU瓶颈的参考指标,如果大于CPU的数量,说明CPU可能不够用了。
但是,在Linux上有点差异!
Linux上的load average除了包括正在使用CPU的进程数量和正在等待CPU的进程数量之外,还包括uninterruptible sleep的进程数量。通常等待IO设备、等待网络的时候,进程会处于uninterruptible sleep状态。Linux设计者的逻辑是,uninterruptible sleep应该都是很短暂的,很快就会恢复运行,所以被等同于runnable。然而uninterruptible sleep即使再短暂也是sleep,何况现实世界中uninterruptible sleep未必很短暂,大量的、或长时间的uninterruptible sleep通常意味着IO设备遇到了瓶颈。众所周知,sleep状态的进程是不需要CPU的,即使所有的CPU都空闲,正在sleep的进程也是运行不了的,所以sleep进程的数量绝对不适合用作衡量CPU负载的指标,Linux把uninterruptible sleep进程算进load average的做法直接颠覆了load average的本来意义。所以在Linux系统上,load average这个指标基本失去了作用,因为你不知道它代表什么意思,当看到load average很高的时候,你不知道是runnable进程太多还是uninterruptible sleep进程太多,也就无法判断是CPU不够用还是IO设备有瓶颈。
从另一个方面来说,也就可以解释为什么磁盘慢时(大量磁盘使用时),CPU负载会飙高了。基本上我碰到CPU负载高的情况就两种情况:CPU本身处理太多任务,再加上软中断和上下文切换太频繁导致负载高;再就是磁盘太慢导致了不可中断睡眠太多导致CPU负载高。
原理:http://linuxperf.com/?p=176