我們將概括和簡要地復習從你按開機按鈕來打開你的 RHEL 7 服務器到呈現(xiàn)出命令行界面的登錄屏幕之間所發(fā)生的所有事情,以此來作為這篇文章的開始。
請注意:
相同的基本原則也可以應用到其他的 Linux 發(fā)行版本中,但可能需要較小的更改,并且
下面的描述并不是旨在給出開機過程的一個詳盡的解釋,而只是介紹一些基礎的東西
初始化 POST(加電自檢)并執(zhí)行硬件檢查;
當 POST 完成后,系統(tǒng)的控制權將移交給啟動管理器的第一階段,它存儲在一個硬盤的引導扇區(qū)(對于使用 BIOS 和 MBR 的舊式的系統(tǒng)而言)或存儲在一個專門的 (U)EFI 分區(qū)上。
啟動管理器的第一階段完成后,接著進入啟動管理器的第二階段,通常大多數(shù)使用的是 GRUB(GRand Unified Boot Loader 的簡稱),它駐留在 /boot
中,然后開始加載內核和駐留在 RAM 中的初始化文件系統(tǒng)(被稱為 initramfs,它包含執(zhí)行必要操作所需要的程序和二進制文件,以此來最終掛載真實的根文件系統(tǒng))。
接著展示了閃屏過后,呈現(xiàn)在我們眼前的是類似下圖的畫面,它允許我們選擇一個操作系統(tǒng)和內核來啟動:
啟動菜單屏幕
內核會對接入到系統(tǒng)的硬件進行設置,當根文件系統(tǒng)被掛載后,接著便啟動 PID 為 1 的進程,這個進程將開始初始化其他的進程并最終呈現(xiàn)給我們一個登錄提示符界面。
注意:假如我們想在啟動后查看這些信息,我們可以使用 dmesg 命令,并使用這個系列里的上一篇文章中介紹過的工具(注:即 grep)來過濾它的輸出。
登錄屏幕和進程的 PID
在上面的例子中,我們使用了大家熟知的 ps
命令來顯示在系統(tǒng)啟動過程中的一系列當前進程的信息,它們的父進程(或者換句話說,就是那個開啟這些進程的進程)為 systemd(大多數(shù)現(xiàn)代的 Linux 發(fā)行版本已經(jīng)切換到的系統(tǒng)和服務管理器):
# ps -o ppid,pid,uname,comm --ppid=1
記住 -o
(為 -format 的簡寫)選項允許你以一個自定義的格式來顯示 ps 的輸出,以此來滿足你的需求;這個自定義格式使用man ps
里 STANDARD FORMAT SPECIFIERS 一節(jié)中的特定關鍵詞。
另一個你想自定義 ps 的輸出而不是使用其默認輸出的情形是:當你需要找到引起 CPU 或內存消耗過多的那些進程,并按照下列方式來對它們進行排序時:
# ps aux --sort=+pcpu # 以 %CPU 來排序(增序)
# ps aux --sort=-pcpu # 以 %CPU 來排序(降序)
# ps aux --sort=+pmem # 以 %MEM 來排序(增序)
# ps aux --sort=-pmem # 以 %MEM 來排序(降序)
# ps aux --sort=+pcpu,-pmem # 結合 %CPU (增序) 和 %MEM (降序)來排列
自定義 ps 命令的輸出
在 Linux 世界中,很少有能比在主流的 Linux 發(fā)行版本中采用 systemd 引起更多的爭論的決定。systemd 的倡導者根據(jù)以下事實來表明其主要的優(yōu)勢:
在系統(tǒng)啟動期間,systemd 允許并發(fā)地啟動更多的進程(相比于先前的 SysVinit,SysVinit 似乎總是表現(xiàn)得更慢,因為它一個接一個地啟動進程,檢查一個進程是否依賴于另一個進程,然后等待守護進程啟動才可以啟動的更多的服務),并且
在一個運行著的系統(tǒng)中,它用作一個動態(tài)的資源管理器。這樣在啟動期間,當一個服務被需要時,才啟動它(以此來避免消耗系統(tǒng)資源)而不是在沒有一個合理的原因的情況下啟動額外的服務。
向后兼容 sysvinit 的腳本。
另外請閱讀: 'init' 和 'systemd' 背后的故事
systemd 由 systemctl 工具控制,假如你了解 SysVinit,你將會對以下的內容感到熟悉:
service 工具,在舊一點的系統(tǒng)中,它被用來管理 SysVinit 腳本,以及
chkconfig 工具,為系統(tǒng)服務升級和查詢運行級別信息
shutdown 你一定使用過幾次來重啟或關閉一個運行的系統(tǒng)。
下面的表格展示了使用傳統(tǒng)的工具和 systemctl 之間的相似之處:
舊式工具 | Systemctl 等價命令 | 描述 |
---|---|---|
service name start | systemctl start name | 啟動 name (這里 name 是一個服務) |
service name stop | systemctl stop name | 停止 name |
service name condrestart | systemctl try-restart name | 重啟 name (如果它已經(jīng)運行了) |
service name restart | systemctl restart name | 重啟 name |
service name reload | systemctl reload name | 重載 name 的配置 |
service name status | systemctl status name | 顯示 name 的當前狀態(tài) |
service - status-all | systemctl | 顯示當前所有服務的狀態(tài) |
chkconfig name on | systemctl enable name | 通過一個特定的單元文件,讓 name 可以在系統(tǒng)啟動時運行(這個文件是一個符號鏈接)。啟用或禁用一個啟動時的進程,實際上是增加或移除一個到 /etc/systemd/system 目錄中的符號鏈接。 |
chkconfig name off | systemctl disable name | 通過一個特定的單元文件,讓 name 可以在系統(tǒng)啟動時禁止運行(這個文件是一個符號鏈接)。 |
chkconfig -list name | systemctl is-enabled name | 確定 name (一個特定的服務)當前是否啟用。 |
chkconfig - list | systemctl - type=service | 顯示所有的服務及其是否啟用或禁用。 |
shutdown -h now | systemctl poweroff | 關機 |
shutdown -r now | systemctl reboot | 重啟系統(tǒng) |
systemd 也引進了單元(unit)(它可能是一個服務,一個掛載點,一個設備或者一個網(wǎng)絡套接字)和目標(target)(它們定義了 systemd 如何去管理和同時開啟幾個相關的進程,可以認為它們與在基于 SysVinit 的系統(tǒng)中的運行級別等價,盡管事實上它們并不等價)的概念。
其他與進程管理相關,但并不僅限于下面所列的功能的任務有:
1. 在考慮到系統(tǒng)資源的使用上,調整一個進程的執(zhí)行優(yōu)先級:
這是通過 renice
工具來完成的,它可以改變一個或多個正在運行著的進程的調度優(yōu)先級。簡單來說,調度優(yōu)先級是一個允許內核(當前只支持 >= 2.6 的版本)根據(jù)某個給定進程被分配的執(zhí)行優(yōu)先級(即友善度(niceness),從 -20 到 19)來為其分配系統(tǒng)資源的功能。
renice
的基本語法如下:
# renice [-n] priority [-gpu] identifier
在上面的通用命令中,第一個參數(shù)是將要使用的優(yōu)先級數(shù)值,而另一個參數(shù)可以是進程 ID(這是默認的設定),進程組 ID,用戶 ID 或者用戶名。一個常規(guī)的用戶(即除 root 以外的用戶)只可以更改他或她所擁有的進程的調度優(yōu)先級,并且只能增加友善度的層次(這意味著占用更少的系統(tǒng)資源)。
進程調度優(yōu)先級
2. 按照需要殺死一個進程(或終止其正常執(zhí)行):
更精確地說,殺死一個進程指的是通過 kill 或 pkill 命令給該進程發(fā)送一個信號,讓它優(yōu)雅地(SIGTERM=15)或立即(SIGKILL=9)結束它的執(zhí)行。
這兩個工具的不同之處在于前一個被用來終止一個特定的進程或一個進程組,而后一個則允許你通過進程的名稱和其他屬性,執(zhí)行相同的動作。
另外, pkill 與 pgrep 相捆綁,pgrep 提供將受符合的進程的 PID 給 pkill 來使用。例如,在運行下面的命令之前:
# pkill -u gacanepa
查看一眼由 gacanepa 所擁有的 PID 或許會帶來點幫助:
# pgrep -l -u gacanepa
找到用戶擁有的 PID
默認情況下,kill 和 pkiill 都發(fā)送 SIGTERM 信號給進程,如我們上面提到的那樣,這個信號可以被忽略(即該進程可能會終止其自身的執(zhí)行,也可能不終止),所以當你因一個合理的理由要真正地停止一個運行著的進程,則你將需要在命令行中帶上特定的 SIGKILL 信號:
# kill -9 identifier # 殺死一個進程或一個進程組
# kill -s SIGNAL identifier # 同上
# pkill -s SIGNAL identifier # 通過名稱或其他屬性來殺死一個進程
在這篇文章中,我們解釋了在 RHEL 7 系統(tǒng)中,有關開機啟動過程的基本知識,并分析了一些可用的工具來幫助你通過使用一般的程序和 systemd 特有的命令來管理進程。
請注意,這個列表并不旨在涵蓋有關這個話題的所有花哨的工具,請隨意使用下面的評論欄來添加你自已鐘愛的工具和命令。同時歡迎你的提問和其他的評論。
聯(lián)系客服