天天看點

Linux基礎之程序管理

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()來建立目前程序的子程序,<code>fork</code> 調用會導緻建立一個子程序,而 <code>exec</code> 調用則會用新程式代替目前程序上下文。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;

<code>-o : 程序起始的ID;</code>

<code>-n  : 程序終止的ID;</code>

<code><code>pgrep -lo httpd 31435 httpd</code></code>

<code><code></code></code>

<code><code>4. pstree:以程序樹的方式來顯示程序間連接配接</code></code>

<code><code>選頃不參數: -A : 各程序樹之間的連接配接以 ASCII 字元來連接配接; -U : 各程序樹之間的連接配接以萬國碼的字元來連接配接。在某些終端接口下可能會有錯誤; -p : 同時列出每個 process的PID; -u : 同時列出每個 process 的所屬賬号名稱。</code></code>

<code><code>pstree -A</code></code>

<code><code>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}]</code></code>

<code>......</code>

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 &lt; sda5 sda6 sda7 &gt; 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 &gt;/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

# See how we were called.

case "$1" in

   start)

       start

       ;;

   stop)

       stop

   restart)

   *)

       echo "Usage: $scriptname{start|stop|restart}" &gt;&amp;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

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

繼續閱讀