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