1 Linux进程简介
内核把进程存放在叫做任务队列(task list)的双向循环链表中,链表中的每一项都是类型为task_struct,名称叫做进程描述符(process descriptor)的结构,该结构定义在include/linux/sched.h文件中,它包含了一个具体进程的所有信息。
进程都是动态创建的,当系统将程序(program)加载到内存中后就会产生一个进程(process)。但init进程不同,它总是存在并且由一个静态的task_struct来表示。
在用户空间,进程是由进程标识符(PID)表示的。从用户的角度来看,一个 PID 是一个数字值,可惟一标识一个进程。一个 PID 在进程的整个生命期间不会更改,但 PID 可以在进程销毁后被重新使用。
创建进程的方式:
1. 直接通过执行一个程序来创建一个新的进程;
2. 通过fork()和exec()来创建当前进程的子进程,fork
调用会导致创建一个子进程,而 exec
调用则会用新程序代替当前进程上下文。Linux下使用了一种叫做写时拷贝(copy-on-write)页实现。这种技术原理是:内存并不复制整个进程地址空间,而是让父进程和子进程共享同一拷贝,只有在需要写入的时候,数据才会被复制。简而言之就是资源的复制只是发生在需要写入的时候才进行,在此之前,都是以只读的方式共享。
父进程和子进程:父进程通过fork()方法产生一个子进程,该子进程与父进程共享同一内存空间,当父进程终止时,子进程也随之而终止。但子进程终止,父进程并不一定终止。
进程的分类:进程一般分为三类,交互式进程、批处理进程和守护进程。其中,守护进程是常驻在内存中的进程,又被称为服务,比如Linux中的系统或网络服务:crond、httpd、mysqld等等。
2 Linux进程管理
2.1 进程的查看:ps、top、pstree
1. ps:静态方式查看当前系统运行的进程
选顷不参数:
-A :所有的process 均显示出来,与-e 具有同样的效果;
-a :与terminal无关其他所有 process ;
-u :有效使用者 (effective user) 相关的process ;
x :通常与-a 这个参数一起使用,可列出较完整信息。
-l:较详细的列出PID的信息;
-f:作出一个更为完整的输出。
ps -l:将目前属于自己这次登入的 PID与相关信息列出来(只与自己的bash 有关)
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 4591 4545 0 80 0 - 2093 - pts/0 00:00:00 su
4 S 0 4632 4591 0 80 0 - 1348 - pts/0 00:00:00 bash
4 R 0 17217 4632 0 80 0 - 1221 - pts/0 00:00:00 ps
0 T 0 26005 4632 0 80 0 - 1099 - pts/0 00:00:00 du
0 T 0 26023 4632 0 80 0 - 3456 - pts/0 00:00:05 du
注解:F:表示此进程的标志(process flags);4表示进程的权限为root,1表示此进程仅进行fork而没有实际执行exec;
S:表示进程状态(STAT);主要状态有:R—Running、S—Sleep、D—不可被唤醒状态、T—stop、Z—Zombie(进程已经终止但无法被移除至内存外)
UID、PID、PPID:表示此进程的用户ID、进程ID、父进程ID
C:代表CPU使用率,单位为百分比
PRI/NI:Priority/Nice 的缩写,代表此进程被 CPU 所执行的优先级,数值越小代表该进程越早被 CPU 执行
ADDR/SZ/WCHAN:与内存有关
TTY:登入的终端
TIME:使用掉的CPU的时间,表示此进程实际消耗的CPU运行的时间,而不是系统时间
CMD:此进程触发的程序名
ps aux:查看系统所有的进程
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 2900 1228 ? Ss Apr01 0:01 /sbin/init
root 2 0.0 0.0 0 0 ? S Apr01 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S Apr01 0:00 [migration/0]
root 4 0.0 0.0 0 0 ? S Apr01 0:05 [ksoftirqd/0]
root 5 0.0 0.0 0 0 ? S Apr01 0:00 [migration/0]
root 6 0.0 0.0 0 0 ? S Apr01 0:00 [watchdog/0]
root 7 0.0 0.0 0 0 ? S Apr01 0:00 [migration/1]
root 8 0.0 0.0 0 0 ? S Apr01 0:00 [migration/1]
root 9 0.0 0.0 0 0 ? S Apr01 0:01 [ksoftirqd/1]
root 10 0.0 0.0 0 0 ? S Apr01 0:00 [watchdog/1]
root 11 0.0 0.0 0 0 ? S Apr01 0:00 [migration/2]
root 12 0.0 0.0 0 0 ? S Apr01 0:00 [migration/2]
root 13 0.0 0.0 0 0 ? S Apr01 0:01 [ksoftirqd/2]
root 14 0.0 0.0 0 0 ? S Apr01 0:00 [watchdog/2]
......
注解:其中很多列都与之前的类似,%MEM表示进程占用内存量,START表示进程被触发启动的时间。
增加-f选项可以显示出父子进程间的关系:ps auxf
nagios 3171 0.0 0.0 9828 1500 ? Ss Apr01 0:35 /usr/local/nagi
nagios 3177 0.0 0.0 3308 804 ? S Apr01 0:01 \_ /usr/local/
nagios 3178 0.0 0.0 3308 808 ? S Apr01 0:01 \_ /usr/local/
nagios 3179 0.0 0.0 3308 808 ? S Apr01 0:01 \_ /usr/local/
.....
2. top:动态的查看进程变化
-d:接秒数,表示进程画面更新的间隔,默认为5秒;
-n:执行的次数,执行完后退出;
-p:指定监测某些PID
在top执行过程可使用的指令:
? :显示在 top 当中可以输入的按键指令;
P :以 CPU 的使用资源排序显示;
M :以 Memory 的使用资源排序显示;
N :以 PID 来排序
T :由该 Process 使用的CPU 时间累积 (TIME+) 排序。
k :给予某个 PID 一个信号(signal)
r :给予某个 PID 重新制订一个 nice 值。
q :离开 top 软件
top -d 2 -n 3 -p 31455
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
Cpu(s): 3.6%us, 0.8%sy, 0.0%ni, 95.2%id, 0.4%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 3896172k total, 3460076k used, 436096k free, 475836k buffers
Swap: 2091000k total, 28000k used, 2063000k free, 2138496k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
31455 apache 20 0 46244 5960 980 S 0.0 0.2 0:00.00 httpd
3. pgrep:通过程序的名字来查询进程
常用参数
-l : 列出程序名和进程ID;
-o : 进程起始的ID;
-n : 进程终止的ID;
pgrep -lo httpd
31435 httpd
4. pstree:以进程树的方式来显示进程间连接
选顷不参数:
-A : 各进程树之间的连接以 ASCII 字符来连接;
-U : 各进程树之间的连接以万国码的字符来连接。在某些终端接口下可能会有错误;
-p : 同时列出每个 process的PID;
-u : 同时列出每个 process 的所属账号名称。
pstree -A
init-+-NetworkManager-+-dhclient
| `-{NetworkManager}
|-abrt-dump-oops
|-abrtd
|-acpid
|-atd
|-automount---4*[{automount}]
|-avahi-daemon---avahi-daemon
|-bonobo-activati---{bonobo-activat}
|-certmonger
|-clock-applet
|-console-kit-dae---63*[{console-kit-da}]
......
2.2 进程管理
singal:给予进程一个singal执行相应的动作,singal代号与名称:
代号 名称 内容
1 SIGHUP 启动被终止的进程,让 PID 重新读取自己的配置文件,类似重新启动
2 SIGINT 相当于用键盘输入 [ctrl]-c 来中断一个进程的运行
9 SIGKILL 代表强制中断一个进程的运行
15 SIGTERM 以正常的方式结束进程的运行,对于某些不正常运行的进程,无法用此singal来终止
17 SIGSTOP 相当于用键盘输入 [ctrl]-z 来暂停一个进程的运行
kill -singal PID:传递singal给某个进程,一般用来终止进程运行,如kill -9 PID强制终止某进程
killall -singal 指令名称:管理与某个程序相关的所有进程,如killall -9 httpd强制终止所有以 httpd 启动的进程
pkill 进程名:以进程名方式杀死指定的正在运行的进程,如pkill httpd
2.3 进程的优先级:Priority、Nice
Priority表示进程之间使用系统资源(cpu、内存等)的优先级,PRI优先值越小表示进程越优先,由内核动态调整,无法人为调整,不过可通过Nice值来调整进程的优先执行顺序。
PRI(new)=PRI(old)+nice
调整nice值的方式:
1. 进程运行时就给定一个特定的nice值,使用nice指令,数值范围为-20~19。如:nice -n -8 ls
2. 通过renice指令来调整某个PID的nice值,如:renice 10 3455
3. 使用top执行过程中的r指令来重新调整某个PID的nice值
3 系统资源查看
3.1 free:查看内存使用情况
-b/-k/-m/-g:free默认以字节显示,可以指定以bytes、Kbytes、Mbytes、Gbytes来显示
-t:在最终结果中显示物理内存和swap总量
free -m
total used free shared buffers cached
Mem: 3804 3375 429 0 469 2092
-/+ buffers/cache: 812 2991
Swap: 2041 27 2014
3.2 uname:查看系统与内核信息
-a :所有系统相关的信息,包括底下的数据都会被列出来;
-s :系统内核名称
-r :内核的版本
-m :本系统的硬件名称,例如 i686或 x86_64 等;
-p :CPU 的类型
-i :硬件的平台 (ix86)
uname -a
Linux rango.com2.6.32-431.11.2.el6.i686 #1 SMP Tue Mar 25 17:17:46 UTC 2014 i686 i686 i386 GNU/Linux
3.3 uptime: 查看系统启动时间和负载
uptime
21:12:48 up 3 days, 2:12, 2 users, load average: 0.09, 0.07, 0.01
3.4 netstat:网络监控
选项与参数:
-a :将目前系统上所有的联机、监听、Socket 数据都列出来
-t :列出 tcp网络封包的数据
-u :列出 udp 网络封包的数据
-n :以端口号 (port number),而不是进程的服务名称来显示;
-l :列出目前正在网络监听(listen) 的朋务;
-p :列出该网络的进程 PID
netstat -tlnp:查找目前系统上已在监听的网络联机及其PID
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:32000 0.0.0.0:* LISTEN 2215/java
tcp 0 0 0.0.0.0:514 0.0.0.0:* LISTEN 2049/rsyslogd
tcp 0 0 127.0.0.1:199 0.0.0.0:* LISTEN 2725/snmpd
......
查看某个端口是否正在被监听:netstat -anl | grep :80
tcp 0 0 :::80 :::* LISTEN
3.5 dmesg:分析内核产生的信息
dmesg | grep sd:查看硬盘相关信息
sd 0:0:0:0: [sda] 976773168 512-byte logical blocks: (500 GB/465 GiB)
sd 0:0:0:0: [sda] 4096-byte physical blocks
sd 0:0:0:0: [sda] Write Protect is off
sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn‘t support DPO or FUA
sda: sda1 sda2 < sda5 sda6 sda7 > sda3 sda4
sd 0:0:0:0: [sda] Attached SCSI disk
EXT4-fs (sda3): mounted filesystem with ordered data mode. Opts:
dracut: Mounted root filesystem /dev/sda3
sd 4:0:0:0: [sdb] Attached SCSI removable disk
sd 0:0:0:0: Attached scsi generic sg0 type 0
sd 4:0:0:0: Attached scsi generic sg2 type 0
Adding 2091000k swap on /dev/sda4. Priority:-1 extents:1 across:2091000k
3.6 vmstat:动态检测系统资源变化
vmstat 可以检测 CPU / 内存 / 磁盘输入输出状态等等。
统计目前主机 CPU 状态,每秒一次,共计三次:vmstat 1 3
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 28000 428940 480996 2141460 0 0 119 52 24 8 4 3 93 1 0
1 0 28000 427468 480996 2143132 0 0 0 0 927 3903 4 1 96 0 0
0 0 28000 427468 480996 2143212 0 0 0 0 981 4040 4 1 96 0 0
注解:
1. procs进程字段:r表示等待运行的进程数量,b表示不可被唤醒的进程数量
2. memory内存字段:swpd虚拟内存被使用的容量,free空闲内存,buff缓冲存储,cache高速缓存
3. swap交换空间:si:由磁盘中将进程取出的量; so:由于内存不足而将没用到的程序写入到磁盘的swap 的容量。 如果 si/so 的数值太大,表示内存内的数据常常得在磁盘与主存储器之间传来传去,系统效能很差
4. io磁盘读写:bi:由磁盘写入的区块数量; bo:写入到磁盘去的区块数量。如果这部份的值越高,代表系统的I/O越繁忙
5. system系统:in:每秒被中断的程序次数; cs:每秒钟进行的事件切换次数;这两个数值越大,代表系统与接口设备的沟通越频繁。 这些接口设备包括磁盘、网卡、时间钟等
6. CPU:us:非核心层的 CPU 使用状态; sy:核心层所使用的 CPU 状态; id:闲置的状态; wa:等待I/O 所耗费的 CPU 状态; st:被虚拟机 (virtual machine) 所盗用的 CPU 使用状态 (2.6.11 以后才支持)。
以watch来执行vmstat:watch vmstat
4 关于SUID/SGID
SUID:Set UID,称为SUID的特殊权限,仅对二进制程序有效,且执行者对该程序有x的可执行权限,以及拥有者owner权限。如ls -l /usr/bin/passwd
-rwsr-xr-x. 1 root root 25980 Feb 22 2012 /usr/bin/passwd
SGID:相应的文件群组所有者的特殊权限。类似的,SGID 对二进制程序有用;程序执行者对于该程序具备 x 的权限;执行者在执行过程中将会获得该程序群组的支持
如ls -l /usr/bin/locate
-rwx--s--x 1 root slocate 35548 Oct 10 2012 /usr/bin/locate
5 使用Supervisord来管理进程
Supervisord是用Python实现的类Unix系统进程管理工具。
Supervisor能够作为跨平台控制者来管理和与进程进行交互,它可以启动、停止、重启其他类Unix系统中的程序,亦可重启崩溃的进程。
1.supervisord:守护进程,用于将指定的程序作为子进程来运行。
2.supervisorctl:supervisor服务控制程序
3.supervisord.conf:配置文件,定义服务名称以及接口等等
ps:如果supervisord要求管理的程序是非daemon程序,supervisord会帮你把它转成daemon程序。
4.通过向supervisord.conf添加[program:daemon]来管理daemon子进程。
eg:
[program:hello]
command=python /home/smallfish/hello.py #command是程序的执行路径
autorstart=true #autorstart是表示自动启动
stdout_logfile=/home/smallfish/hello.log #stdout_logfile是捕获标准输出
5.安装Supervisor:
easy_install supervisor
或者:
wget http://pypi.python.org/packages/source/s/supervisor/supervisor-3.0b1.tar.gz
tar -zxvf supervisor-3.0b1.tar.gz
cd supervisor-3.0b1
python setup.py install
6.设定supervisor配置文件:
创建默认的配置文件:
echo_supervisord_conf >/etc/supervisord.conf
vi /etc/supervisord.conf
取消以下的注释,并修改IP为0.0.0.0,表示监听所有主机的9001端口。并添加basic authenrication
[inet_http_server] ; inet (TCP)server disabled by default
port=0.0.0.0:9001 ;(ip_address:port specifier, *:port for all iface)
username=rango ; (defaultis no username (open server))
password=yourkey ;(default is no password (open server))
增加自定义的后台进程(注意进程名之间用一个:分隔)
[program:daemon]
command=python/scripts/python/daemon.py
autorestart=true
stdout_logfile=/tmp/daemon.log
7.设定supervisor启动文件:
#!/bin/bash
#
# supervisordStartup script for thesupervisor
#
# description: Supervisor is aclient/server system that allows its users to # monitor andcontrol a number of processes on UNIX-like #operating systems.
path=/sbin:/bin:/usr/sbin:/usr/bin
prog=supervisord
daemon=/usr/bin/$prog
config=/etc/$prog.conf
pidfile=/tmp/$prog.pid
desc="supervisord daemon"
scriptname=/etc/init.d/$prog
# Gracefully exit if the package hasbeen removed.
test -x $daemon || exit 0
start() {
echo -n "Starting $desc:$prog"
$daemon -c $config
echo "..."
}
stop() {
echo -n "Stoping $desc:$prog"
supervisor_pid=$(cat $pidfile)
kill -15 $supervisor_pid
echo "..."
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo "Usage: $scriptname{start|stop|restart}" >&2
exit 1
;;
esac
exit 0
添加可执行权限:chmod +x /etc/init.d/supervisord
8.编写相应的python脚本:
vim /scripts/python/daemon.py:
#!/usr/bin/env python
import time
print "Daemon runs 3 secs, then dies"
time.sleep(3)
print "Daemon dies"
启动supervisor服务,并观察daemon服务状态:
/etc/init.d/supervisord start
tail -f /tmp/daemon.log:
Daemon runs 3 secs, then dies
Daemon dies
Daemon runs 3 secs, then dies
Daemon dies
Daemon runs 3 secs, then dies
Daemon dies
Daemon runs 3 secs, then dies
Daemon dies
Daemon runs 3 secs, then dies
Daemon dies
Daemon runs 3 secs, then dies
Daemon dies
9.Web界面访问:http://localhost:9001
ps:防火墙开启服务:
vim /etc/sysconfig/iptables:
-A INPUT -m state --state NEW -m tcp -p tcp --dport 9001 -j ACCEP
——Rango Chen
本文出自 “游响云停” 博客,请务必保留此出处http://rangochen.blog.51cto.com/2445286/1390794