程序管理

程序的观察

ps :将某个时间点的程序运行情况撷取下来

[root@www ~]# ps aux  <==观察系统所有的程序数据
[root@www ~]# ps -lA  <==也是能够观察所有系统的数据
[root@www ~]# ps axjf <==连同部分程序树状态
选项与参数:
-A  :所有的 process 均显示出来,与 -e 具有同样的效用;
-a  :不与 terminal 有关的所有 process ;
-u  :有效使用者 (effective user) 相关的 process ;
x   :通常与 a 这个参数一起使用,可列出较完整资讯。
输出格式规划:
l   :较长、较详细的将该 PID 的的资讯列出;
j   :工作的格式 (jobs format)
-f  :做一个更为完整的输出。
  • 仅观察自己的 bash 相关程序: ps -l

    范例一:将目前属於您自己这次登陆的 PID 与相关资讯列示出来(只与自己的 bash 有关)
    [root@www ~]# ps -l
    F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
    4 S     0 13639 13637  0  75   0 -  1287 wait   pts/1    00:00:00 bash
    4 R     0 13700 13639  0  77   0 -  1101 -      pts/1    00:00:00 ps
    
      F:代表这个程序旗标 (process flags),说明这个程序的总结权限,常见号码有:
      若为 4 表示此程序的权限为 root ;
      若为 1 则表示此子程序仅进行复制(fork)而没有实际运行(exec)。
    
      S:代表这个程序的状态 (STAT),主要的状态有:
      R (Running):该程序正在运行中;
      S (Sleep):该程序目前正在睡眠状态(idle),但可以被唤醒(signal)。
      D :不可被唤醒的睡眠状态,通常这支程序可能在等待 I/O 的情况(ex>列印)
      T :停止状态(stop),可能是在工作控制(背景暂停)或除错 (traced) 状态;
      Z (Zombie):僵尸状态,程序已经终止但却无法被移除至内存外。
    
      UID/PID/PPID:代表『此程序被该 UID 所拥有/程序的 PID 号码/此程序的父程序 PID 号码』
    
      C:代表 CPU 使用率,单位为百分比;
    
      PRI/NI:Priority/Nice 的缩写,代表此程序被 CPU 所运行的优先顺序,数值越小代表该程序越快被 CPU 运行。详细的 PRI 与 NI 将在下一小节说明。
    
      ADDR/SZ/WCHAN:都与内存有关,ADDR 是 kernel function,指出该程序在内存的哪个部分,如果是个 running 的程序,一般就会显示『 - 』 / SZ 代表此程序用掉多少内存 / WCHAN 表示目前程序是否运行中,同样的, 若为 - 表示正在运行中。
    
      TTY:登陆者的终端机位置,若为远程登陆则使用动态终端介面 (pts/n);
    
      TIME:使用掉的 CPU 时间,注意,是此程序实际花费 CPU 运行的时间,而不是系统时间;
    
      CMD:就是 command 的缩写,造成此程序的触发程序之命令为何。
    
  • 观察系统所有程序: ps aux

      范例二:列出目前所有的正在内存当中的程序:
      [root@www ~]# ps aux
      USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
      root         1  0.0  0.0   2064   616 ?        Ss   Mar11   0:01 init [5]
      root         2  0.0  0.0      0     0 ?        S<   Mar11   0:00 [migration/0]
      root         3  0.0  0.0      0     0 ?        SN   Mar11   0:00 [ksoftirqd/0]
      .....(中间省略).....
      root     13639  0.0  0.2   5148  1508 pts/1    Ss   11:44   0:00 -bash
      root     14232  0.0  0.1   4452   876 pts/1    R+   15:52   0:00 ps aux
      root     18593  0.0  0.0   2240   476 ?        Ss   Mar14   0:00 /usr/sbin/atd
    
      USER:该 process 属於那个使用者帐号的?
      PID :该 process 的程序识别码。
      %CPU:该 process 使用掉的 CPU 资源百分比;
      %MEM:该 process 所占用的实体内存百分比;
      VSZ :该 process 使用掉的虚拟内存量 (Kbytes)
      RSS :该 process 占用的固定的内存量 (Kbytes)
      TTY :该 process 是在那个终端机上面运行,若与终端机无关则显示 ?,另外, tty1-tty6 是本机上面的登陆者程序,若为 pts/0 等等的,则表示为由网络连接进主机的程序。
      STAT:该程序目前的状态,状态显示与 ps -l 的 S 旗标相同 (R/S/T/Z)
      START:该 process 被触发启动的时间;
      TIME :该 process 实际使用 CPU 运行的时间。
      COMMAND:该程序的实际命令为何?
    

top:动态观察程序的变化

[root@www ~]# top [-d 数字] | top [-bnp]
选项与参数:
-d  :后面可以接秒数,就是整个程序画面升级的秒数。默认是 5 秒;
-b  :以批量的方式运行 top ,还有更多的参数可以使用喔!
      通常会搭配数据流重导向来将批量的结果输出成为文件。
-n  :与 -b 搭配,意义是,需要进行几次 top 的输出结果。
-p  :指定某些个 PID 来进行观察监测而已。
在 top 运行过程当中可以使用的按键命令:
    ? :显示在 top 当中可以输入的按键命令;
    P :以 CPU 的使用资源排序显示;
    M :以 Memory 的使用资源排序显示;
    N :以 PID 来排序喔!
    T :由该 Process 使用的 CPU 时间累积 (TIME+) 排序。
    k :给予某个 PID 一个讯号  (signal)
    r :给予某个 PID 重新制订一个 nice 值。
    q :离开 top 软件的按键。
范例一:每两秒钟升级一次 top ,观察整体资讯:
[root@www ~]# top -d 2
top - 17:03:09 up 7 days, 16:16,  1 user,  load average: 0.00, 0.00, 0.00
Tasks:  80 total,   1 running,  79 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.5%us,  0.5%sy,  0.0%ni, 99.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:    742664k total,   681672k used,    60992k free,   125336k buffers
Swap:  1020088k total,       28k used,  1020060k free,   311156k cached
    <==如果加入 k 或 r 时,就会有相关的字样出现在这里喔!

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND     
14398 root      15   0  2188 1012  816 R  0.5  0.1   0:00.05 top
    1 root      15   0  2064  616  528 S  0.0  0.1   0:01.38 init
    2 root      RT  -5     0    0    0 S  0.0  0.0   0:00.00 migration/0
    3 root      34  19     0    0    0 S  0.0  0.0   0:00.00 ksoftirqd/0
第一行(top...):这一行显示的资讯分别为:
目前的时间,亦即是 17:03:09 那个项目;
启动到目前为止所经过的时间,亦即是 up 7days, 16:16 那个项目;
已经登陆系统的使用者人数,亦即是 1 user项目;
系统在 1, 5, 15 分钟的平均工作负载。我们在第十六章谈到的 batch 工作方式为负载小於 0.8 就是这个负载罗!代表的是 1, 5, 15 分钟,系统平均要负责运行几个程序(工作)的意思。 越小代表系统越闲置,若高於 1 得要注意你的系统程序是否太过繁复了!

第二行(Tasks...):显示的是目前程序的总量与个别程序在什么状态(running, sleeping, stopped, zombie)。 比较需要注意的是最后的 zombie 那个数值,如果不是 0 !好好看看到底是那个 process 变成僵尸了吧?

第三行(Cpus...):显示的是 CPU 的整体负载,每个项目可使用 ? 查阅。需要特别注意的是 %wa ,那个项目代表的是 I/O wait, 通常你的系统会变慢都是 I/O 产生的问题比较大!因此这里得要注意这个项目耗用 CPU 的资源喔! 另外,如果是多核心的设备,可以按下数字键『1』来切换成不同 CPU 的负载率。

第四行与第五行:表示目前的实体内存与虚拟内存 (Mem/Swap) 的使用情况。 再次重申,要注意的是 swap 的使用量要尽量的少!如果 swap 被用的很大量,表示系统的实体内存实在不足!

第六行:这个是当在 top 程序当中输入命令时,显示状态的地方。

top 下半部分的画面,则是每个 process 使用的资源情况:

PID :每个 process 的 ID  
USER:该 process 所属的使用者;
PR :Priority 的简写,程序的优先运行顺序,越小越早被运行;
NI :Nice 的简写,与 Priority 有关,也是越小越早被运行;
%CPU:CPU 的使用率;
%MEM:内存的使用率;
TIME+:CPU 使用时间的累加;

top 默认使用 CPU 使用率 (%CPU) 作为排序的重点,如果你想要使用内存使用率排序,则可以按下『M』, 若要回复则按下『P』即可。如果想要离开 top 则按下『 q 』

pstree

[root@www ~]# pstree [-A|U] [-up]
选项与参数:
-A  :各程序树之间的连接以 ASCII 字节来连接;
-U  :各程序树之间的连接以万国码的字节来连接。在某些终端介面下可能会有错误;
-p  :并同时列出每个 process 的 PID;
-u  :并同时列出每个 process 的所属帐号名称。

范例一:列出目前系统上面所有的程序树的相关性:
[root@www ~]# pstree -A
init-+-acpid
     |-atd
     |-auditd-+-audispd---{audispd}  <==这行与底下一行为 auditd 分出来的子程序
     |        `-{auditd}
     |-automount---4*[{automount}]   <==默认情况下,相似的程序会以数字显示
....(中间省略)....
     |-sshd---sshd---bash---pstree   <==就是我们命令运行的那个相依性!
....(底下省略)....
# 注意一下,为了节省版面,所以鸟哥已经删去很多程序了!

范例二:承上题,同时秀出 PID 与 users 
[root@www ~]# pstree -Aup
init(1)-+-acpid(4555)
        |-atd(18593)
        |-auditd(4256)-+-audispd(4258)---{audispd}(4261)
        |              `-{auditd}(4257)
        |-automount(4536)-+-{automount}(4537) <==程序相似但 PID 不同!
        |                 |-{automount}(4538)
        |                 |-{automount}(4541)
        |                 `-{automount}(4544)
....(中间省略)....
        |-sshd(4586)---sshd(16903)---bash(16905)---pstree(16967)
....(中间省略)....
        |-xfs(4692,xfs)   <==因为此程序拥有者并非运行 pstree 者!所以列出帐号
....(底下省略)....
# 在括号 () 内的即是 PID 以及该程序的 owner 喔!不过,由於我是使用 
# root 的身份运行此一命令,所以属於 root 的程序就不会显示出来啦!

关於程序的运行顺序

Priority 与 Nice 值

PRI 值越低代表越优先的意思。不过这个 PRI 值是由核心动态调整的, 使用者无法直接调整 PRI 值的

[root@www ~]# ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0 18625 18623  2  75   0 -  1514 wait   pts/1    00:00:00 bash
4 R     0 18653 18625  0  77   0 -  1102 -      pts/1    00:00:00 ps

当 nice 值为负值时,那么该程序就会降低 PRI 值,亦即会变的较优先被处理。此外,你必须要留意到:

* nice 值可调整的范围为 -20 ~ 19 ;
* root 可随意调整自己或他人程序的 Nice 值,且范围为 -20 ~ 19 ;
* 一般使用者仅可调整自己程序的 Nice 值,且范围仅为 0 ~ 19 (避免一般用户抢占系统资源);
* 一般使用者仅可将 nice 值越调越高,例如本来 nice 为 5 ,则未来仅能调整到大於 5;

调整某个程序的优先运行序有两种方式:

  • 一开始运行程序就立即给予一个特定的 nice 值:用 nice 命令;
  • 调整某个已经存在的 PID 的 nice 值:用 renice 命令。

1. nice :新运行的命令即给予新的 nice 值

[root@www ~]# nice [-n 数字] command 
选项与参数:
-n  :后面接一个数值,数值的范围 -20 ~ 19。

范例一:用 root 给一个 nice 值为 -5 ,用於运行 vi ,并观察该程序!
[root@www ~]# nice -n -5 vi &
[1] 18676
[root@www ~]# ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0 18625 18623  0  75   0 -  1514 wait   pts/1    00:00:00 bash
4 T     0 18676 18625  0  72  -5 -  1242 finish pts/1    00:00:00 vi
4 R     0 18678 18625  0  77   0 -  1101 -      pts/1    00:00:00 ps
# 原本的 bash PRI 为 75  ,所以 vi 默认应为 75。不过由於给予 nice  为 -5 ,
# 因此 vi 的 PRI 降低了!但并非降低到 70 ,因为核心还会动态调整!

[root@www ~]# kill -9 %1 <==测试完毕将 vi 关闭

2. renice :已存在程序的 nice 重新调整

[root@www ~]# renice [number] PID
选项与参数:
PID :某个程序的 ID 啊!

范例一:找出自己的 bash PID ,并将该 PID 的 nice 调整到 10
[root@www ~]# ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0 18625 18623  0  75   0 -  1514 wait   pts/1    00:00:00 bash
4 R     0 18712 18625  0  77   0 -  1102 -      pts/1    00:00:00 ps

[root@www ~]# renice 10 18625
18625: old priority 0, new priority 10

[root@www ~]# ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0 18625 18623  0  85  10 -  1514 wait   pts/1    00:00:00 bash
4 R     0 18715 18625  0  87  10 -  1102 -      pts/1    00:00:00 ps

系统资源的观察

free :观察内存使用情况

[root@www ~]# free [-b|-k|-m|-g] [-t]
选项与参数:
-b  :直接输入 free 时,显示的单位是 Kbytes,我们可以使用 b(bytes), m(Mbytes)
      k(Kbytes), 及 g(Gbytes) 来显示单位喔!
-t  :在输出的最终结果,显示实体内存与 swap 的总量。

范例一:显示目前系统的内存容量
[root@www ~]# free -m
          total       used    free   shared   buffers    cached
Mem:        725        666      59        0       132       287
-/+ buffers/cache:     245     479
Swap:       996          0     996

系统是『很有效率的将所有的内存用光光』, 目的是为了让系统的存取效能加速一般来说, swap 最好不要被使用,尤其 swap 最好不要被使用超过 20% 以上, 如果您发现 swap 的用量超过 20% ,那么,最好还是买实体内存来插吧! 因为, Swap 的效能跟实体内存实在差很多,而系统会使用到 swap , 绝对是因为实体内存不足了才会这样做的。

uname:查阅系统与核心相关资讯

[root@www ~]# uname [-asrmpi]
选项与参数:
-a  :所有系统相关的资讯,包括底下的数据都会被列出来;
-s  :系统核心名称
-r  :核心的版本
-m  :本系统的硬件名称,例如 i686 或 x86_64 等;
-p  :CPU 的类型,与 -m 类似,只是显示的是 CPU 的类型!
-i  :硬件的平台 (ix86)

范例一:输出系统的基本资讯
[root@www ~]# uname -a
Linux www.vbird.tsai 2.6.18-92.el5 #1 SMP Tue Jun 10 18:49:47 EDT 2008 i686
i686 i386 GNU/Linux

uptime:观察系统启动时间与工作负载

[root@www ~]# uptime
 15:39:13 up 8 days, 14:52,  1 user,  load average: 0.00, 0.00, 0.00
# 这个 uptime 可以显示出 top 画面的最上面一行

netstat :追踪网络或插槽档

[root@www ~]# netstat -[atunlp]
选项与参数:
-a  :将目前系统上所有的连线、监听、Socket 数据都列出来
-t  :列出 tcp 网络封包的数据
-u  :列出 udp 网络封包的数据
-n  :不以程序的服务名称,以埠号 (port number) 来显示;
-l  :列出目前正在网络监听 (listen) 的服务;
-p  :列出该网络服务的程序 PID 

范例一:列出目前系统已经创建的网络连线与 unix socket 状态
[root@www ~]# netstat
Active Internet connections (w/o servers) <==与网络较相关的部分
Proto Recv-Q Send-Q Local Address        Foreign Address      State
tcp        0    132 192.168.201.110:ssh  192.168.:vrtl-vmf-sa ESTABLISHED
Active UNIX domain sockets (w/o servers)  <==与本机的程序自己的相关性(非网络)
Proto RefCnt Flags       Type       State         I-Node Path
unix  20     [ ]         DGRAM                    9153   /dev/log
unix  3      [ ]         STREAM     CONNECTED     13317  /tmp/.X11-unix/X0
unix  3      [ ]         STREAM     CONNECTED     13233  /tmp/.X11-unix/X0
unix  3      [ ]         STREAM     CONNECTED     13208  /tmp/.font-unix/fs7100
....(中间省略)....

在上面的结果当中,显示了两个部分,分别是网络的连线以及 linux 上面的 socket 程序相关性部分。 先来看看网际网络连线情况的部分:

Proto :网络的封包协议,主要分为 TCP 与 UDP 封包,相关数据请参考服务器篇;
Recv-Q:非由使用者程序连结到此 socket 的复制的总 bytes 数;
Send-Q:非由远程主机传送过来的 acknowledged 总 bytes 数;
Local Address :本地端的 IP:port 情况
Foreign Address:远程主机的 IP:port 情况
State :连线状态,主要有创建(ESTABLISED)及监听(LISTEN);

上表中 socket file 的输出栏位有:

Proto :一般就是 unix 啦;
RefCnt:连接到此 socket 的程序数量;
Flags :连线的旗标;
Type :socket 存取的类型。主要有确认连线的 STREAM 与不需确认的 DGRAM 两种;
State :若为 CONNECTED 表示多个程序之间已经连线创建。
Path :连接到此 socket 的相关程序的路径!或者是相关数据输出的路径。

dmesg :分析核心产生的信息

系统在启动的时候,核心会去侦测系统的硬件,你的某些硬件到底有没有被捉到,那就与这个时候的侦测有关。行过程中,反正只要是核心产生的信息,都会被记录到内存中的某个保护区段。 dmesg 这个命令就能够将该区段的信息读出来

范例一:输出所有的核心启动时的资讯
[root@www ~]# dmesg | more

范例二:搜寻启动的时候,硬盘的相关资讯为何?
[root@www ~]# dmesg | grep -i hd
    ide0: BM-DMA at 0xd800-0xd807, BIOS settings: hda:DMA, hdb:DMA
    ide1: BM-DMA at 0xd808-0xd80f, BIOS settings: hdc:pio, hdd:pio
hda: IC35L040AVER07-0, ATA DISK drive
hdb: ASUS DRW-2014S1, ATAPI CD/DVD-ROM drive
hda: max request size: 128KiB
....(底下省略)....

vmstat :侦测系统资源变化

vmstat 可以侦测『 CPU / 内存 / 磁碟输入输出状态 』等等,如果你想要了解一部繁忙的系统到底是哪个环节最累人, 可以使用 vmstat 分析看看。

[root@www ~]# vmstat [-a] [延迟 [总计侦测次数]] <==CPU/内存等资讯
[root@www ~]# vmstat [-fs]                      <==内存相关
[root@www ~]# vmstat [-S 单位]                  <==配置显示数据的单位
[root@www ~]# vmstat [-d]                       <==与磁碟有关
[root@www ~]# vmstat [-p 分割槽]                <==与磁碟有关
选项与参数:
-a  :使用 inactive/active(活跃与否) 取代 buffer/cache 的内存输出资讯;
-f  :启动到目前为止,系统复制 (fork) 的程序数;
-s  :将一些事件 (启动至目前为止) 导致的内存变化情况列表说明;
-S  :后面可以接单位,让显示的数据有单位。例如 K/M 取代 bytes 的容量;
-d  :列出磁碟的读写总量统计表
-p  :后面列出分割槽,可显示该分割槽的读写总量统计表

范例一:统计目前主机 CPU 状态,每秒一次,共计三次!
[root@www ~]# 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     28  61540 137000 291960    0    0     4     5   38   55  0  0 100  0  0
 0  0     28  61540 137000 291960    0    0     0     0 1004   50  0  0 100  0  0
 0  0     28  61540 137000 291964    0    0     0     0 1022   65  0  0 100  0  0
内存栏位 (procs) 的项目分别为:
r :等待运行中的程序数量;b:不可被唤醒的程序数量。这两个项目越多,代表系统越忙碌 (因为系统太忙,所以很多程序就无法被运行或一直在等待而无法被唤醒之故)。

内存栏位 (memory) 项目分别为:
swpd:虚拟内存被使用的容量; free:未被使用的内存容量; buff:用於缓冲内存; cache:用於高速缓存。 这部份则与 free 是相同的。

内存置换空间 (swap) 的项目分别为:
si:由磁碟中将程序取出的量; so:由於内存不足而将没用到的程序写入到磁碟的 swap 的容量。 如果 si/so 的数值太大,表示内存内的数据常常得在磁碟与主内存之间传来传去,系统效能会很差!

磁碟读写 (io) 的项目分别为:
bi:由磁碟写入的区块数量; bo:写入到磁碟去的区块数量。如果这部份的值越高,代表系统的 I/O 非常忙碌!

系统 (system) 的项目分别为:
in:每秒被中断的程序次数; cs:每秒钟进行的事件切换次数;这两个数值越大,代表系统与周边设备的沟通非常频繁! 这些周边设备当然包括磁碟、网络卡、时间钟等。

CPU 的项目分别为:
us:非核心层的 CPU 使用状态; sy:核心层所使用的 CPU 状态; id:闲置的状态; wa:等待 I/O 所耗费的 CPU 状态; st:被虚拟机器 (virtual machine) 所盗用的 CPU 使用状态 (2.6.11 以后才支持)。