在Linux系統裡,當前正在啟動並執行程式執行個體稱
為進程。比如,當你啟動Apache的時候,系統會為它分配一個進程ID。然後就可以用
這個ID監視和控制這個程式。
進程監視和控制是任何Linux系統管理員的核心任務。一個管理員可以終止("kill"
)、重啟一個進程,甚至可以為它指定一個不同的優先順序。標準的Linux命令"ps"和
"top"通常用於查看當前的進程列表。下面我來說明如何用這些命令和其它命令來管
理Linux系統中的進程。
用ps監視進程
一個監視Linux的標準工具就是"ps",它是進程狀態的簡稱。這個命令返回正在運行
的程式的資訊。這些資訊可能包括程式是在哪個使用者名稱下啟動並執行,使用了多少CPU以
及運行了多長時間。如果你要手工終止程式或者確定是哪個程式讓系統變慢時,這些
資訊是很有用的。
如果你只是鍵入了"ps"這個命令,那麼只能列出運行在當前終端下的進程。下面的例
子是通過遠程shell運行"ps"輸出的結果:
$ ps
PID TTY TIME CMD
4684 pts/14 00:00:00 bash
27107 pts/14 00:00:00 ps
從輸出可以看出,分配給這個使用者/終端的進程只有Bash shell和ps命令本身。你還
可以看到為每個進程列出的PID(進程ID)和TTY、TIME和CMD。TTY指明這個進程正在
運行在哪個終端上,TIME指明了這個進程已經使用了多少CPU時間,CMD則是啟動這個
進程的命令名稱。
使用者可以看到,標準的ps命令只能列出基本的資訊。要想獲得Linux系統上啟動並執行進
程的詳細資料,你必須加入一些命令列參數。
加入ps常用的aux參數後可以顯示其他使用者啟動的進程(a)、查看系統中屬於自己的
進程(x)以及啟動這個進程的使用者和它啟動的時間(u)。
表A樣本了ps aux命令的輸出。
現在還有其它更多的資訊,增加了USER、 %CPU、%MEM、 VSZ、RSS、STAT和START這
幾個域。現在我們來看一下這些資訊是什麼含義。
首先,使用者可以看到所有的進程,而不僅僅是運行在終端上的那些。USER域指明了是
哪個使用者啟動了這個命令。很多進程和系統一起啟動,而且會把根或者一些系統帳號
列為USER。當然,其它一些進程是單獨啟動並執行。這個資訊本身就可以協助你縮小問題
範圍。假如某個使用者啟動了指令碼,佔用了伺服器大量的I/O。如果能馬上找到是誰在
運行這個程式,那麼就可以大大加快解決問題的速度。
%CPU、 %MEM、VSZ和RSS這幾個域都與系統資源有關。首先,使用者可以查看某個進程
佔用了多少CPU。這個資訊是即時顯示的,所以很難用ps捕捉峰值。可能使用者會發現
,為了找到引發問題的那個進程需要不停地運行ps命令。
除了CPU使用方式,還可以看到記憶體使用量及其VSZ(虛擬記憶體大小)和RSS(常駐集大
小)。VSZ表示如果一個程式完全駐留在記憶體的話需要佔用多少記憶體空間,而RSS指明
了當前實際佔用了多少記憶體。如果能夠瞭解一個進程當前佔用了多少記憶體,那麼就可
以確定這個進程是在正常運行還是出現了異常。程式通常都會消耗比正常情況更多的
記憶體和CPU。雖然程式員都在儘力確保代碼正確地使用資源,但是有時候還是要由管
理員來決定終止還是重啟進程。
使用者可能會注意到在ps aux命令的輸出結果裡,大部分TTY域有個"?"。這是因為這
些程式或者在系統啟動的時候就開始運行了,或者是由初始化指令碼(init script)
啟動的。這些進程沒有控制終端,所以作了標記。另外,linux-sanity-check命令有
一個TTY的值為pts/14。這個命令是遠端連線啟動並執行,有與其關聯的一個終端。當你
的機器開放了多條串連,而你又想確定某個命令運行在哪個視窗的時候,這個資訊是
很有用的。
STAT顯示了進程當前的狀態。在我們的例子裡,很多進程處在睡眠狀態,STAT域裡的
"S"指明了這一狀態。這僅僅表明這些進程在等待某些事件發生--可能是使用者輸入或
者系統資源的可用性。linux-sanity-check命令則有一個R狀態,這個狀態表明進程
當前正在運行。有時候你可以瀏覽一下這個列表然後找那些R狀態的進程。如果大部
分進程處在睡眠狀態而又有問題發生,那麼只關注那些正在啟動並執行進程是最好的方法
。那種狀態不一定能說明發生了問題,但是有時候如果進程啟動並執行時間過長可能意味
著發生了某些深層次的問題。
用top監視進程
另外一個有用的程式就是top。這個程式和ps類似,但是通常會全螢幕顯示,而且會隨
著進程狀態的變化不斷更新。對於那些經常引發問題,而用ps又難以查看的程式而言
,這個命令是很有用的。整個系統的資訊也會顯示,這就為著手尋找問題提供了便利
。系統總共有多少CPU和記憶體資源以及Server Load Balancer等資訊本身就是很有用的,再加上程
序列表以及程式當前的狀態和各自的統計資訊,你現在可以理解為什麼top這麼常用
了。
不要忘了pstree
最後,另外一個可以快速簡單查看進程的命令是pstree。這個命令會列出當前的進程
以及它們的樹結構。一個進程啟動的時候可能會產生自己的一個子進程。運行pstree
命令就可以很容易地看到這些資訊。
$ pstree -cp 125
httpd(125)-+-httpd(126)
|-httpd(127)
| -httpd(129)
`-httpd(130)
Httpd是個很好的例子,因為它會經常產生子進程。在上例中你可以看到PID為125的
樹。如果你想終止httpd但是又不想結束所有單個的子進程,那麼找父進程。pstree
命令可以列出所有單個進程對應的樹或者系統中的所有進程。它不僅可以協助你找到
發生異常的進程,還可以作為一個學習工具。使用者可以通過執行這些命令學到Linux
的很多東西,還可以參考相關的協助頁。
管理進程
如果你學會了用ps和top這些命令監視進程,你還應該知道怎麼管理進程。你可以用
kill、killall和renice這些命令實現進程管理。
"kill"命令向正在啟動並執行進程發送訊號。最常見的應用就是用它來停止程式的執行。
你首先要獲得運行進程的PID(比如可以用ps aux命令),然後可以用如下命令終止
進程:
$ kill 125
$ kill -9 125
通常情況下這個命令可以終止進程125。需要強調的是你要麼是這個進程的屬主,要
麼是根使用者,否則不能終止這個進程。有時候單純用一個kill命令並不能終止進程,
你還需要以下操作:
如果進程掛起而且沒有正常回應,那麼可以用"-9"標誌來結束這個進程,上例指明了
這個過程。通常的kill命令是發送一個sigterm訊號,而-9發送的是sigkill訊號,這
個訊號強迫程式終止。其它一些訊號可以用於終止或者啟動進程。你可以運行"kill
-l"命令,然後就可以看到這些內容。
Killall命令與kill命令很相似,但是接收不同的參數。你可以向它傳送一個程式名
而不是PID。以這個程式名啟動並執行所有進程都會被終止。只要你是程式的屬主或者是
根使用者那麼就可以終止這個程式。所以運行killall tcpdump命令會終止所有tcpdump
程式的執行個體。如果有很多進程以同樣的名字運行,這一點是很有用的。
一定要注意你在終止什麼進程,特別在你是根使用者的時候。終止了不適當的進程可能
終止你的會話甚至讓整個系統都停止運行。你應該熟悉那些標準的運行進程以及它們
的資源使用方式。如果想防止系統問題發生,最好設定一個基準。
還記不記得我先前提到可以改變進程的優先順序?你可以用renice命令實現。改變優先
級可以通知系統給某個進程更多或者更少的CPU時間。進程優先順序("niceness")的
範圍從-20到20,-20是最高的優先順序。所以如果想要減小httpd進程125的優先順序,你
可以運行下面的命令:
$ renice +20 125
你可以通過改變優先順序來節省系統資源。系統可以自動改變優先順序,每當這種情況發
生的時候,很可能意味著一個程式佔用了比正常情況下更多的資源。
加速問題解決過程
能夠監視和控制Linux系統中的進程是很必要的。ps、top、kill和renice這些程式可
以讓你看到進程的運行情況並且對它進行控制。你對每個進程瞭解得越多,就能夠越
容易地精確定位進程的問題所在。系統通常會因為某種原因遇到各種問題,比如速度
變慢或者不穩定,而使用這些工具可以協助你提高找到問題所在的能力。