18.系統進程和性能管理,計劃任務
- 內核功用:進程管理、文件系統、網絡功能、內存管理、驅動程序、 安全功能等
- Process: 運行中的程序的一個副本,是被載入內存的一個指令集合
進程ID(Process ID,PID)號碼被用來標記各個進程
UID、 GID、和SELinux語境決定對文件系統的存取和訪問權限
通常從執行進程的用戶來繼承
它存在生命周期- task struct:Linux內核存儲進程信息的數據結構格式
- task list:多個任務的的task struct組成的鏈表
- 進程創建:
init:第一個進程
進程:都由其父進程創建,父子關系,CoW,fork(), clone()
註意:
- 進程和不是程序,它是程序加載到內存中之後進行運行的各種指令操作的集合
- 程序運行時先將它加載到內核空間內存中,然後再將它分配到用戶空間內存中中,此時相當於系統分配給它一個獨立的內存空間。這時候它便成為了進程,並且和其他的進程相互隔離。它認為自己獨占了整個內存空間(虛擬出來的內存,並非真實的內存空間),並在此基礎上進行操作。實際上它占用的只是系統給它分配的一小塊內存空間而已。
- 進程運行時會隨機分配一個進程編號,運行結束之後會被會被回收。它運行時就相當於一個資源的集合,有自己的獨立的內存,能讀取數據進去,有自己的二進制執行程序命令,包括很多縣城等等。
- 進程內部真正執行操作計算的是線程,一個線程就是各種指令的集合。一個進程內至少有一個線程,可以有多個。
- 進程的生命周期有長期的(後臺進程),有一次性短期運行的(前臺進程)。比如說開機就開始運行的init進程,還有cat ls等程序的進程。
- task struct : 一個數據結構,包含了進程的各種元數據。
- 創建子進程如果用clone()函數,就會產生CoW(寫時復制)方式,類似邏輯卷中的快照:只有子進程中對數據進行修改了,才會重新創建一個不同的數據存放於子進程中。而數據並未更改時它和父進程指向同一個數據,共用此數據。(最開始學習中的小括號開啟子進程,小括號內局部變量如果不賦值,仍然和父進程的變量內容一樣就是這個原因)
- 協程就是多個命令的集合代碼塊(類似函數),多個協程組成一個線程。進程中線程的執行順序的優先級是由操作系統內核來調度的,而CPU在同一時間只能運行一個線程。我們人看到進程的執行感覺它是同時執行的,其實它只是利用CPU的時間頻率分成了多個時間段,然後一個時間段執行一個線程,由內核調度,不論是否完成這個線程,只要時間段一到,它就會切換到另一個線程進行運行,保存當前線程的狀態,這也就是所謂的上下文切換(註意,線程切換可以是不同進程的線程,也就相當於切換了不同的進程)。因為CPU頻率極快,因此我們看起來它貌似是同步執行了多個進程。
- 上下文切換會造成CPU內的當前線程(或進程)緩存數據(L1,L2,L3)失效,相比於CPU的運算時間,這個代價非常巨大,因此要盡量避免上下文切換進行優化。
進程,線程和協程
進程相關概念
- Page Frame: 頁框,用存儲頁面數據,存儲Page 4k (也就是進程使用的內存空間,類似磁盤的塊block)
- 物理地址空間和線性地址空間:物理上的實際內存和應用程序使用時認為的虛擬內存(相當於偏移地址)
- MMU:Memory Management Unit 負責轉換線性和物理地址,CPU內的內存管理單元
- TLB:Translation Lookaside Buffer 翻譯後備緩沖器,用於保存虛擬地址和物理地址映射關系的緩存
- LRU:Least Recently Used :內存保存數據的算法,被叫做近期最少使用算法,用於釋放內存,它的工作原理就是把最新使用的數據存放到內存空間靠前的位置。
比如說一個數據存入內存,如果內存中已經存在此數據,則把它的位置提前到內存空間起始位置,如果沒有,則存入,並把內存空間終止位置保存的的數據給丟棄(類似堆棧)。
用戶和內核空間
進程的基本狀態和轉換
進程的基本狀態
- 創建狀態:進程在創建時需要申請一個空白PCB(process control block進程控制塊),向其中填寫控制和管理進程的信息,完成資源分配。如果創建工作無法完成,比如資源無法滿足,就無法被調度運行,把此時進程所處狀態稱為創建狀態
- 就緒狀態:進程已準備好,已分配到所需資源,只要分配到CPU就能夠立即運行
- 執行狀態:進程處於就緒狀態被調度後,進程進入執行狀態
- 阻塞狀態:正在執行的進程由於某些事件(I/O請求,申請緩存區失敗)而暫時無法運行,進程受到阻塞。在滿足請求時進入就緒狀態等待系統調用
- 終止狀態:進程結束,或出現錯誤,或被系統終止,進入終止狀態。無法再執行
狀態之間轉換情況
- 運行——>就緒:1,主要是進程占用CPU的時間過長,而系統分配給該進程占用CPU的時間是有限的;2,在采用搶先式優先級調度算法的系統中,當有更高優先級的進程要運行時,該進程就被迫讓出CPU,該進程便由執行狀態轉變為就緒狀態
- 就緒——>運行:運行的進程的時間片用完,調度就轉到就緒隊列中選擇合適的進程分配CPU
- 運行——>阻塞:正在執行的進程因發生某等待事件而無法執行,則進程由執行狀態變為阻塞狀態,如發生了I/O請求
- 阻塞——>就緒:進程所等待的事件已經發生,就進入就緒隊列
- 以下兩種狀態是不可能發生的:
- 阻塞——>運行:即使給阻塞進程分配CPU,也無法執行,操作系統在進行調
度時不會從阻塞隊列進行挑選,而是從就緒隊列中選取 - 就緒——>阻塞:就緒態根本就沒有執行,談不上進入阻塞態
IPC進程間通信
IPC: Inter Process Communication
同一主機:
pipe 管道
socket 套接字文件
signal 信號
shm shared memory
semaphore 信號量,一種計數器
不同主機:
socket IP和端口號
RPC remote procedure call
MQ 消息隊列,如:Kafka,RabbitMQ,ActiveMQ
- 單一主機通訊用socket文件,全雙工;跨網絡通訊用socket套接字協議。
進程優先級
- 系統優先級:數字越小,優先級越高
0-139:各有140個運行隊列和過期隊列
實時優先級: 99-0 值最大優先級最高
nice值:-20到19,對應系統優先級100-139 - Big O:時間復雜度,用時和規模的關系
O(1), O(logn), O(n)線性, O(n^2)拋物線, O(2^n)
O(1)比較優先級大小的方式:
- 通過140個編號的優先級隊列以及140個過時優先級隊列,將優先級編號相同的進程放在對應的優先級棧中(一個優先級棧可以放多個進程,從左往右執行),然後從最小值(最高優先級)的隊列開始執行。
- 當時間片到而此運行隊列中的正在執行的進程沒有執行完畢時,便會保存當前進程狀態並將此進程放入相同優先級編號過期隊列中,然後繼續執行當前優先級隊列中的剩余進程(一個進程在時間片內執行完了就釋放,沒有執行完同樣放入過期優先級隊列中),直到此隊列的所有進程全部執行一遍,將此隊列清空
- 此時查看此隊列相同編號的過時優先級隊列,裏面如果有進程,則將此隊列的與過期優先級隊列互換身份,此運行隊列變成過期優先級隊列,而過期優先級隊列變成正在執行的運行隊列。然後重復2中步驟直到此隊列的所有進程全部執行完畢並且釋放
- 接下來就是執行下一個最高優先級隊列裏面的進程了,重復1-4步驟。
進程狀態
Linux內核:搶占式多任務
- 進程類型:
守護進程: daemon,在系統引導過程中啟動的進程,和終端無關進程
前臺進程:跟終端相關,通過終端啟動的進程
註意:兩者可相互轉化 - 進程狀態:
運行態:running
就緒態:ready
睡眠態:
可中斷:interruptable :可中斷睡眠狀態是系統中進程最多的狀態
不可中斷:uninterruptable
停止態:stopped,暫停於內存,但不會被調度,除非手動啟動
僵死態:zombie,結束進程,父進程結束前,子進程不關閉 - 註意僵死態的進程已經結束了,但是仍然占用部分資源,kill命令無法再次關閉它,最好的方法就是殺掉父進程或者重啟系統。
系統管理工具
進程的分類:
CPU-Bound:CPU密集型,非交互 :比如編譯
IO-Bound:IO密集型,交互 :網絡吞吐,磁盤讀寫
Linux系統狀態的查看及管理工具:pstree, ps, pidof, pgrep, top, htop,glance, pmap, vmstat, dstat, kill, pkill, job, bg, fg, nohup
- pstree命令:
pstree display a tree of processes
查看進程進程ps
- ps: process state
ps report a snapshot of the current processes :查看ps命令執行時的進程快照
Linux系統各進程的相關信息均保存在/proc/PID目錄下的各文件中 - ps [OPTION]...
支持三種選項:
UNIX選項 如-A -e
BSD選項 如a
GNU選項 如--help - 選項:不加選項時,默認顯示鏈接到當前終端中的進程,無法顯示別的終端中進程
a 選項包括鏈接到所有終端中的進程
x 選項包括不鏈接終端的進程
u 選項顯示進程所有者的信息
f 選項顯示進程樹,相當於 --forest
k|--sort 屬性 對屬性排序,屬性前加- 表示倒序 : 比如 ps aux k -%cpu ,註意後面的關鍵字要小寫不能大寫
o 屬性… 選項顯示定制的信息 pid、 cmd、 %cpu、 %mem
L 顯示支持的屬性列表
短格式(unix)特有選項
-C cmdlist 指定命令,多個命令用逗號,分隔 :也可以查看腳本,但要註意用 bash XXX.sh 方式運行的腳本無法查看, 同時如果腳本中沒有 #!/bin/bash 就算是直接運行的腳本也無法查看了。
-L 顯示線程 : pstree中花括號內就是線程,如果沒有花括號代表進程只有一個線程(此命令就會顯示進程了)
-e: 顯示所有進程,相當於-A
-f: 顯示完整格式程序信息
-F: 顯示更完整格式的進程信息
-H: 以進程層級格式顯示進程相關信息
-u userlist 指定有效的用戶ID或名稱
-U userlist 指定真正的用戶ID或名稱
-g gid或groupname 指定有效的gid或組名稱
-G gid或groupname 指定真正的gid或組名稱
-p pid 顯示指pid的進程
--ppid pid 顯示屬於pid的子進程
-M 顯示SELinux信息,相當於Z
- 註意:有效用戶和真正用戶區別,真正用戶是指執行此進程的用戶realuser,而有效用戶代表此進程執行的的權限用戶,比如普通用戶執行passwd命令,真正用戶為普通用戶但有效用戶為root。(組類似)
ps axo pid,cmd,user,ruser,euser ,其中 user和euser 相同意義,代表有效權限用戶 ,ruser代表真正執行用戶
ps 輸出屬性
VSZ: Virtual memory SiZe,虛擬內存集,線性內存
- 進程向操作系統申請的內存,它的數值可以很大,但並非全部都使用,是個虛擬內存,按照進程自己定義的地址方式來尋址使用
RSS: ReSident Size, 常駐內存集 - 內核真正分配的內存大小,常駐內存
STAT:進程狀態
R:running
S: interruptable sleeping
D: uninterruptable sleeping
T: stopped
Z: zombie
+: 前臺進程
l: 多線程進程
L:內存分頁並帶鎖
N:低優先級進程
\<\: 高優先級進程
s: session leader,會話(子進程)發起者
START:進程啟動的時間,和date相關
TIME:此進程啟動後運行所占的時間片累計總時間
PS中優先級類別
ni(或者nice): nice值
pri: priority 優先級
psr: processor CPU編號
rtprio: 實時優先級
- 附加知識:renice -n -10(優先級-20~19) 8814(PID),修改進程nice優先級
- nice -n -5 ping 1.1.1.1 :直接指定命令的nice優先級,(默認為0改為-5)
- 附加知識:chrt 修改實時優先級,不過一般不調整它,它是系統自動分配設置的,一般只修改nice用戶級別的優先級
- 註意: pri優先級應該是和前面圖中系統優先級剛好相反;不過有一個特例就是當realtime優先級為0時,它也為0,而不是40,其他的都還符合。
示例:
ps axo pid,cmd,psr,ni,pri,rtprio
常用組合:
aux
-ef
-eFH
-eo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,comm
axo stat,euid,ruid,tty,tpgid,sess,pgrp,ppid,pid,pcpu,comm
示例:
- 查詢你擁有的所有進程
ps -x - 顯示指定用戶名(RUID)或用戶ID的進程
ps -fU apache
ps -fU 48 - 顯示指定用戶名(EUID)或用戶ID的進程
ps -fu wang
ps -fu 1000 - 查看以root用戶權限(實際和有效ID)運行的每個進程
ps -U root -u root - 列出某個組擁有的所有進程(實際組ID:RGID或名稱)
ps -fG nginx - 列出有效組名稱(或會話)所擁有的所有進程
ps -fg mysql
ps -fg 27 - 顯示指定的進程ID對應的進程
ps -fp 1234 - 以父進程ID來顯示其下所有的進程,如顯示父進程為1234的所有進程
ps -f --ppid 1234 - 顯示指定PID的多個進程
ps -fp 1204,1239,1263 - 要按tty顯示所屬進程
ps -ft pts/0 - 以進程樹顯示系統中的進程如何相互鏈接
ps -e --forest - 以進程樹顯示指定的進程
ps -f --forest -C sshd
ps -ef --forest | grep -v grep | grep sshd - 要顯示一個進程的所有線程,將顯示LWP(輕量級進程)以及NLWP(輕量級進程數)列
ps -fL -C nginx - 要列出所有格式說明符
ps L - 查看進程的PID,PPID,用戶名和命令
ps -eo pid,ppid,user,cmd - 自定義格式顯示文件系統組,ni值開始時間和進程的時間
ps -p 1234 -o pid,ppid,fgroup,ni,lstart,etime - 使用其PID查找進程名稱:
ps -p 1244 -o comm= - 要以其名稱選擇特定進程,顯示其所有子進程
ps -C sshd,bash - 查找指定進程名所有的所屬PID,在編寫需要從std輸出或文件讀取PID的腳本時這個參數很有用
ps -C httpd,sshd -o pid= - 檢查一個進程的執行時間
ps -eo comm,etime,user | grep nginx - 查找占用最多內存和CPU的進程
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu | head - 顯示安全信息
ps -eM
ps --context - 使用以下命令以用戶定義的格式顯示安全信息
ps -eo euser,ruser,suser,fuser,f,comm,label - 使用watch實用程序執行重復的輸出以實現對就程進行實時的監視,如下面的命令顯示每秒鐘的監視
watch -n 1 ‘ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head‘
進程優先級
- 進程優先級調整
靜態優先級:100-139
進程默認啟動時的nice值為0,優先級為120
只有根用戶才能降低nice值(提高優先性) - nice命令
nice [OPTION] [COMMAND [ARG]...] - renice命令
renice [-n] priority pid... - 查看
ps axo pid,comm,ni
搜索進程
- 最靈活方式:ps 選項 | 其它命令
- 按預定義的模式:pgrep
pgrep [options] pattern
-u uid: effective user,生效者
-U uid: real user,真正發起運行命令者
-t terminal: 與指定終端相關的進程
-l: 顯示進程名
-a: 顯示完整格式的進程名
-P pid: 顯示指定進程的子進程- 更多詳細內容查看幫助即可
- 按確切的程序名稱:/sbin/pidof
pidof bash- 註意它和lsof區別,lsof跟的是被打開的文件(或者程序,因為程序也是文件),pidof跟的就是進程名(程序如果沒運行不是進程)
例子:
- 註意它和lsof區別,lsof跟的是被打開的文件(或者程序,因為程序也是文件),pidof跟的就是進程名(程序如果沒運行不是進程)
pgrep -lU zhang
pgrep -aU zhang
pgrep -P 1
pgrep -at pts/1
pgrep -f sshd
poidof bash
Pidof更多用法
pidof 進程名 :
通過查看上面命令的$? 值可以判斷進程是否停止運行了,因此就可以編寫腳本監測必須運行的進程,一旦發現停止立馬重新啟動(配合計劃任務使用極佳,當然也可以用killall 0 的方式也可)
例如:如果ping命令沒有執行,則ping 127.0.0.1,如果ping命令已經執行(不管ping的IP地址是什麽),則不執行ping 127.0.0.1
pidof ping &> /dev/null || ping 127.0.0.1
系統工具
- /proc/uptime 包括兩個值,單位 s秒
系統啟動時長,空閑進程的總時長(按總的CPU核心數計算) - uptime 和 w
顯示當前時間,系統已啟動的時間、當前上線人數,系統平均負載(當前時間往前1、 5、 10分鐘的平均負載,一般不會超過1) - 系統平均負載:
指在特定時間間隔內運行隊列中的平均進程數- 通常每個CPU內核的當前活動進程數不大於3,那麽系統的性能良好。 如果每個CPU內核的任務數大於5,那麽此主機的性能有嚴重問題
- 如果linux主機是1個雙核CPU,當Load Average 為6的時候說明機器已經被充分使用
進程管理工具
top:有許多內置命令
- 排序:
P:以占據的CPU百分比,%CPU
M:占據內存百分比,%MEM
T:累積占據CPU時長,TIME+ - 首部信息顯示:
uptime信息:l命令
tasks及cpu信息:t命令
cpu分別顯示:1 (數字)
memory信息:m命令
退出命令:q
修改刷新時間間隔:s
終止指定進程:k
保存文件:W
-
欄位信息簡介:
us:用戶空間
sy:內核空間
ni:調整nice時間
id:空閑
wa:等待IO時間
hi:硬中斷
si:軟中斷(模式切換)
st:虛擬機偷走的時間(虛擬化技術不成熟時期,不知道CPU的時間片執行了什麽進程) - 選項:
-d # 指定刷新時間間隔,默認為3秒
-b 全部顯示所有進程
-n # 刷新多少次後退出
-H 線程模式,示例:top -H -p `pidof mysqld`
htop命令:EPEL源
-
選項:
-d #: 指定延遲時間;
-u UserName: 僅顯示指定用戶的進程
-s COLUME: 以指定字段進行排序 - 子命令:
s:跟蹤選定進程的系統調用
l:顯示選定進程打開的文件列表
a:將選定的進程綁定至某指定CPU核心
t:顯示進程樹
內存空間
內存空間使用狀態:free [OPTION]
-b 以字節為單位
-m 以MB為單位
-g 以GB為單位
-h 易讀格式
-o 不顯示-/+buffers/cache行
-t 顯示RAM + swap的總和
-s n 刷新間隔為n秒
-c n 刷新n次後即退出
註意bufer和cache區別
- 簡單來說一個註重寫一個註重讀,不過後期因為有相同的部分它倆區別越來越小
- 註意磁盤掛載的時候有選項可直接寫入硬盤 mount -o sync ,同時TCP協議中報頭數據psh位置也是表示內存是否立即取走。
vmstat命令:虛擬內存信息
vmstat [options] [delay [count]]
vmstat 2 5
- procs:
r:可運行(正運行或等待運行)進程的個數,和核心數有關
b:處於不可中斷睡眠態的進程個數(被阻塞的隊列的長度),比如正在讀取磁盤文件的進程(IO接口速度慢,需要耗費時間) - memory:
swpd: 交換內存的使用總量
free:空閑物理內存總量
buffer:用於buffer的內存總量
cache:用於cache的內存總量 - swap:(註意是相對於內存的進和出來說的,磁盤進出下同)
si:從磁盤交換進內存的數據速率(kb/s)
so:從內存交換至磁盤的數據速率(kb/s)
-io:
bi:從塊設備讀入數據到系統的速率(kb/s)
bo: 保存數據至塊設備的速率
dd if=/dev/zero of=/dev/null bs=2G :則swap中 so先漲,然後si再漲
dd if=/dev/sda of=/dev/null :則io中的bi 漲 ,bo不變
dd if=/dev/zero of=/dev/sda1/bigfile :則io中的bi不變 ,bo漲
- system:
in: interrupts 中斷速率,包括時鐘
cs: context switch 進程切換速率 - cpu:
us:Time spent running non-kernel code
sy: Time spent running kernel code
id: Time spent idle. Linux 2.5.41前,包括IO-wait time.
wa: Time spent waiting for IO. 2.5.41前,包括in idle.
st: Time stolen from a virtual machine. 2.6.11前, unknown. - 選項:
-s: 顯示內存的統計數據
系統監控工具
iostat:統計CPU和設備IO信息
示例:iostat 1 10
iftop:顯示帶寬使用情況,EPEL源
示例:iftop -n -i eth1
pmap命令:進程對應的內存映射(占用了哪些內存空間,地址從哪到哪,以及一些調用的庫函數)
pmap [options] pid [...]
-x: 顯示詳細格式的信息
示例:pmap 1
- 另外一種實現
cat /proc/PID/maps
用pmap來判斷內存問題,看某個程序的內存占用是否一直增長判斷它內存泄露
- 內存泄露:進程執行完畢不釋放所占的內存空間
- 內存溢出:進程申請執行時所用的內存空間不夠,直接霸占更多的內存空間進行使用(可能影響其他進程,如果多霸占的內存空間正好被其他進程使用中)
glances命令:EPEL源
glances [-bdehmnrsvyz1] [-B bind] [-c server] [-C conffile] [-p port] [-P password] [--password] [-t refresh] [-f file] [-o output]
-
內建命令:
a Sort processes automatically
c Sort processes by CPU%
m Sort processes by MEM%
p Sort processes by name
i Sort processes by I/O rate
d Show/hide disk I/O stats
f Show/hide file system stats
n Show/hide network stats
s Show/hide sensors stats
y Show/hide hddtemp stats
l Show/hide logs
b Bytes or bits for network I/O
w Delete warning logs
x Delete warning and critical logs
1 Global CPU or per-CPU stats
h Show/hide this help screen
t View network I/O as combination
u View cumulative network I/O
q Quit (Esc and Ctrl-C also work) - 常用選項:
-b: 以Byte為單位顯示網卡數據速率
-d: 關閉磁盤I/O模塊
-f /path/to/somefile: 設定輸入文件位置
-o {HTML|CSV}:輸出格式
-m: 禁用mount模塊
-n: 禁用網絡模塊
-t #: 延遲時間間隔
-1:每個CPU的相關數據單獨顯示
C/S模式下運行glances命令
- 服務器模式:
glances -s -B IPADDR
IPADDR: 指明監聽的本機哪個地址 - 客戶端模式:
glances -c IPADDR
IPADDR:要連入的服務器端地址 - 註意兩個主機上都要裝有glances工具,並且版本要一致(6和6,7和7),然後開啟服務器的監聽功能之後,客戶機就可以隨時連接監聽服務器端了。
dstat命令:系統資源統計,代替vmstat,iostat
dstat [-afv] [options..] [delay [count]]
-c 顯示cpu相關信息
-C #,#,...,total
-d 顯示disk相關信息
-D total,sda,sdb,...
-g 顯示page相關統計數據
-m 顯示memory相關統計數據
-n 顯示network相關統計數據
-p 顯示process相關統計數據
-r 顯示io請求相關的統計數據
-s 顯示swapped相關的統計數據
--tcp
--udp
--unix
--raw
--socket
--ipc
--top-cpu:顯示最占用CPU的進程
--top-io: 顯示最占用io的進程
--top-mem: 顯示最占用內存的進程
--top-latency: 顯示延遲最大的進程
iotop
iotop命令是一個用來監視磁盤I/O使用狀況的top類工具iotop具有與top相似的UI,其中包括PID、用戶、I/O、進程等相關信息,可查看每個進程是如何使用IO
- iotop輸出
第一行:Read和Write速率總計
第二行:實際的Read和Write速率
第三行:參數如下:
線程ID(按p切換為進程ID)
優先級
用戶
磁盤讀速率
磁盤寫速率
swap交換百分比
IO等待所占的百分比
線程/進程命令
iotop常用參數
-o, --only只顯示正在產生I/O的進程或線程,除了傳參,可以在運行過程中按o生效
-b, --batch非交互模式,一般用來記錄日誌
-n NUM, --iter=NUM設置監測的次數,默認無限。在非交互模式下很有用
-d SEC, --delay=SEC設置每次監測的間隔,默認1秒,接受非×××數據例如1.1
-p PID, --pid=PID指定監測的進程/線程
-u USER, --user=USER指定監測某個用戶產生的I/O
-P, --processes僅顯示進程,默認iotop顯示所有線程
-a, --accumulated顯示累積的I/O,而不是帶寬
-k, --kilobytes使用kB單位,而不是對人友好的單位。在非交互模式下,腳本編程有用
-t, --time 加上時間戳,非交互非模式
-q, --quiet 禁止頭幾行,非交互模式,有三種指定方式
-q 只在第一次監測時顯示列名
-qq 永遠不顯示列名
-qqq 永遠不顯示I/O匯總
交互按鍵
left和right方向鍵:改變排序
r:反向排序
o:切換至選項--only
p:切換至--processes選項
a:切換至--accumulated選項
q:退出
i:改變線程的優先級
nload 查看網絡實時吞吐量
- nload是一個實時監控網絡流量和帶寬使用情況,以數值和動態圖展示進出的流量情況
- 安裝:yum -y install nload (EPEL源)
-
界面操作
上下方向鍵、左右方向鍵、 enter鍵或者tab鍵都就可以切換查看多個網卡的流量情況
按 F2 顯示選項窗口
按 q 或者 Ctrl+C 退出 nload - 示例:
nload:默認只查看第一個網絡的流量進出情況
nload eth0 eth1:在nload後面指定網卡,可以指定多個 - 設置刷新間隔:默認刷新間隔是100毫秒,可通過-t命令設置刷新時間(單位是毫秒)
nload -t 500 eth0 - 設置單位:顯示兩種單位一種是顯示Bit/s、一種是顯示Byte/s,默認是以Bit/s,也可不顯示/s
-u h|b|k|m|g|H|B|K|M|G 表示的含義: h: auto, b: Bit/s, k: kBit/s, m: MBit/s, H:auto, B: Byte/s, K: kByte/s, M: MByte/s - 例子: nload -u M eth0
lsof
lsof:list open files 查看當前系統文件的工具。在linux環境下,一切皆文件,用戶通過文件不僅可以訪問常規數據,還可以訪問網絡連接和硬件如傳輸控制協議(TCP)和用戶數據報協議(UDP)套接字等,系統在後臺都為該應用程序分配了一個文件描述符
- 命令參數
-a:列出打開文件存在的進程
-c<進程名>:列出指定進程所打開的文件
-g:列出GID號進程詳情
-d<文件號>:列出占用該文件號的進程
+d<目錄>:列出目錄下被打開的文件
+D<目錄>:遞歸列出目錄下被打開的文件
-n<目錄>:列出使用NFS的文件
-i<條件>:列出符合條件的進程(4、 6、協議、 :端口、 @ip )
-p<進程號>:列出指定進程號所打開的文件
-u:列出UID號進程詳情
-h:顯示幫助信息
-v:顯示版本信息。
-n: 不反向解析網絡名字
lsof示例
進程管理
- 查看由登陸用戶啟動而非系統啟動的進程
lsof /dev/pts/1 - 指定進程號,可以查看該進程打開的文件
lsof -p 9527
文件管理
- 查看指定程序打開的文件
lsof -c httpd - 查看指定用戶打開的文件
lsof -u root | more - 查看指定目錄下被打開的文件
lsof +D /var/log/
lsof +d /var/log/- 參數+D為遞歸列出目錄下被打開的文件,參數+d為列出目錄下被打開的文件
- 查看所有網絡連接
lsof -i –n
lsof [email protected]
通過參數-i查看網絡連接的情況,包括連接的ip、端口等以及一些服務的連接情況,例如:sshd等。也可以通過指定ip查看該ip的網絡連接情況 - 查看端口連接情況
lsof -i :80 -n
通過參數-i:端口可以查看端口的占用情況,-i參數還有查看協議,ip的連接情況等 - 查看指定進程打開的網絡連接
lsof -i –n -a -p 9527
參數-i、 -a、 -p等,-i查看網絡連接情況,-a查看存在的進程,-p指定進程 - 查看指定狀態的網絡連接
lsof -n -P -i TCP -s TCP:ESTABLISHED
-n:no host names, -P:no port names,-i TCP指定協議,-s指定協議狀態通過多個參數可以清晰的查看網絡連接情況、協議連接情況等
8. 恢復刪除文件(前提是這個刪除文件仍然被進程占用著還在內存中)
lsof |grep /var/log/messages
rm -f /var/log/messages
lsof |grep /var/log/messages 或者 grep delede :這一步找到它的進程編號,下一步進入進程編號文件夾
cat /proc/653/fd/6
cat /proc/653/fd/6 > /var/log/messages
進程管理工具
kill命
- 向進程發送控制信號,以實現對進程管理,每個信號對應一個數字,信號名稱以SIG開、頭(可省略),不區分大小寫
- 顯示當前系統可用信號: kill –l 或者 trap -l
- 常用信號:man 7 signal
(1) SIGHUP 無須關閉進程而讓其重讀配置文件
(2) SIGINT 中止正在運行的進程;相當於Ctrl+c 例如kill -2 `pidof ping`
(3) SIGQUIT 相當於ctrl+\ :,有些命令用它退出,可用 kill -QUIT `pidof bc`或者 kill -3
(9) SIGKILL 強制殺死正在運行的進程:強制退出
(15) SIGTERM 終止正在運行的進程:正常退出
(18) SIGCONT 繼續運行
(19) SIGSTOP 後臺休眠 - 指定信號的方法 :
(1) 信號的數字標識:1, 2, 9
(2) 信號完整名稱:SIGHUP
(3) 信號的簡寫名稱:HUP
例子:kill -1
cd /var/www/html
echo welcome to my web >index.html
curl 192.168.20.100
vim /etc/httpd/conf/httpd.conf :其中的頁面文件位置修改為newhtml
mkdir newhtml
cd newhtml
vim index.html :重新寫一個新的頁面文件
ps auxf 或者 ps -ef 或者 pidof httpd|apache 或者 pstree -p
kill -1 apache的父進程pid(由root啟動的那個pid)
kill -n 1 pid :註意一個帶-一個不帶-
例子:kill -15 (默認)
ps aux |grep mingetty
kill mingettypid :此命令執行後發現pid號雖然沒了,但是會生成一個新的pid號把它重新掛起
pstree -p :查看是哪一個父進程拉起mingetty,發現是1進程
kill 1 :殺不死1進程,但是此時再次執行 kill pidmingetty 發現它無法再自動起來了,說明此命令對於1進程還是有影響的
因此不要隨便用kill殺進程,比如殺掉sshd服務,則遠程將無法再次連接,必須在硬件主機上面重啟sshd :systemctl start sshd 才可以再次使用,這將有可能出現嚴重問題
- 按PID:
kill [-SIGNAL] pid …
kill –n SIGNAL pid
kill –s SIGNAL pid - 按名稱:killall [-SIGNAL] comm… :它可以一次性殺掉對應名字進程包含的所有pid ,而kill 一次只能殺掉一個
- 按模式:pkill [options] pattern (正則表達式)
-SIGNAL :
-u uid: effective user,生效者
-U uid: real user,真正發起運行命令者
-t terminal: 與指定終端相關的進程
-l: 顯示進程名(pgrep可用)
-a: 顯示完整格式的進程名(pgrep可用)
-P pid: 顯示指定進程的子進程
例子:
pkill -9 -t pts/1 :把終端上全部進程殺掉包括bash shell
pkill pin.* :正則表達式模式法殺掉ping(或者pin開頭的任意進程))
killall -0 cmdname 的用法
此命令不進行進程管理,但是會檢查cmd名進程是否正常運行,類似於pidof ,把返回值存入$?中,用於判斷cmd進程是否正常運行。
任務作業管理
- Linux的作業控制
前臺作業:通過終端啟動,且啟動後一直占據終端
後臺作業:可通過終端啟動,但啟動後即轉入後臺運行(釋放終端) - 讓作業運行於後臺
(1) 運行中的作業: Ctrl+z ,它會放入後端但是讓它處於stop休眠狀態
(2) 尚未啟動的作業: COMMAND &- 註意:後臺作業雖然被送往後臺運行,但其依然與終端相關;退出當前終端,將關閉後臺作業。如果希望送往後臺後,剝離與終端的關系,有以下兩種方式:
- nohup COMMAND &> /dev/null &
- screen;COMMAND
- 查看當前終端所有作業:jobs
- 作業控制:
fg [[%]JOB_NUM]:把指定的後臺作業調回前臺
bg [[%]JOB_NUM]:讓送往後臺的作業在後臺繼續運行
kill [%JOB_NUM]: 終止指定的作業
易混淆點:
- killall -18 手動開啟休眠狀態的進程 ,killall -19 手動停止正在運行的進程。這兩個命令和前端,後端沒有任何關系,和終端也沒有關系,只要能找到進程,就可用它操作(也可用pstree -p 或則 pidof 或者 ps aux 找到進程編號然後kill -18 -19也可)
- 進程和終端相關是因為它是在終端內開了個子shell來運行的,只要終端關閉(比如遠程sshd服務終端關閉),父進程都關閉了那麽它下面的無論是前端還是後端任務都將會關閉,例如關閉終端相當於關閉6681進程,則ping命令當然會關閉,無論前端後端。
├─sshd(6994)─┬─sshd(6681)───bash(6683)───ping(6773)
│ └─sshd(129671)───bash(129673)───pstree(6808)
- 上面都是centos7中的邏輯,但是centos6中,如果終端關閉,則它下面的子進程會自動掛載到init上繼續運行,註意區分。
- 因此用nohup將命令運行之後,當終端關閉它會掛載到systemd上繼續運行。或者還可用screen程序,則終端掉了也不會影響命令的執行。
- 註意,command & 和 ctrl z 的區別,一個已經運行調到後端不運行,一個沒有運行調到後端運行。
- 註意fg會把後端的進城調回到前端並運行,不管它在後端否運行還是不運行。同樣的bg也是讓進程調回到後端進行運行,只不過因為進程前段運行的時候無法操作,同時也沒有jobs編號,所以已經運行進程要用ctrl+z調到後端停止運行,然後再用bg 啟動運行。
並行運行
- 同時運行多個進程,提高效率(相當於同時啟動多個後臺程序)
- 方法1
vi all.sh
f1.sh &
f2.sh &
f3.sh &
然後運行此腳本 - 方法2
(f1.sh &);(f2.sh &);(f3.sh &) - 方法3:註意中括號邊上有空格
{ f1.sh & f2.sh & f3.sh & }
- 方法1
任務計劃
Linux任務計劃、周期性任務執行
未來的某時間點執行一次任務
at 指定時間點,執行一次性任務
batch 系統自行選擇空閑時間去執行此處指定的任務
周期性運行某任務
cron
at任務
包:at
at 命令:at [option] TIME
常用選項:
-V 顯示版本信息
-t time 時間格式 [[CC]YY]MMDDhhmm[.ss]
-l 列出指定隊列中等待運行的作業;相當於atq
-d 刪除指定的作業;相當於atrm
-c #(編號) :查看具體作業任務
-f /path/file 指定的文件中讀取任務
-m 當任務被完成之後,將給用戶發送郵件,即使沒有標準輸出
- 註意:作業執行命令的結果中的標準輸出和錯誤以郵件通知給相關用戶
TIME格式:定義出什麽時候進行 at 這項任務的時間
HH:MM [YYYY-mm-dd]
noon, midnight, teatime(4pm)
tomorrow
now+#{minutes,hours,days, OR weeks}
- HH:MM 02:00
在今日的 HH:MM 進行,若該時刻已過,則明天此時執行任務 - HH:MM YYYY-MM-DD 02:00 2016-09-20
規定在某年某月的某一天的特殊時刻進行該項任務 - HH:MM[am|pm] [Month] [Date]
04pm March 17
17:20 tomorrow - HH:MM[am|pm] + number [minutes|hours|days|weeks]
在某個時間點再加幾個時間後才進行該項任務
now + 5 min
02pm + 3 days- 註意:測試中發現如果設置的時間小於當前時間點(比如現在時間3點,執行命令2點)則它會明天執行(即使此時把時間改為1點59分它也不會馬上執行了,因為還有日期的關系,別忘記了)需要註意這一點(crontab中也是這個原理)。
執行方式:
(1)交互式 (2)輸入重定向(多行)(3)管道| (4)at –f 文件
它依賴於atd服務,需要啟動才能實現at任務
rpm -ql at
systemctl status|start atd.service
at DATE<<EOF :一行一個任務
xxx
xxx
EOF
at -l
- 註意at交互式的話需要用ctrl+d結束。
at隊列存放在/var/spool/at目錄中
/etc/at.{allow,deny}控制用戶是否能執行at任務
- 白名單:/etc/at.allow 默認不存在,只有該文件中的用戶才能執行at命令
- 黑名單:/etc/at.deny 默認存在,拒絕該文件中用戶執行at命令,而沒有在at.deny 文件中的使用者則可執行
註意點:
- 如果存在了白名單,則黑名單無效了,如果兩個文件都不存在,只有 root 可以執行 at 命令。
- 直接用at命令寫的計劃任務重啟後丟失。
- at 中的計劃任務命令中的標準輸出不會在屏幕上打印,它會自動寫入郵件中發送。用-m可以讓沒有標準輸出的命令也發郵件,為了證明此at任務確實執行了
周期性任務計劃cron
周期性任務計劃:cron
相關的程序包:
cronie:主程序包,提供crond守護進程及相關輔助工具
cronie-anacron:cronie的補充程序,用於監控cronie任務執行狀況,如cronie中的任務在過去該運行的時間點未能正常運行,則anacron會隨後啟動一次此任務
crontabs:包含CentOS提供系統維護任務
- 確保crond守護處於運行狀態:
CentOS 7:
systemctl status crond
CentOS 6:
service crond status - 計劃周期性執行的任務提交給crond,到指定時間會自動運行系統cron任務:系統維護作業
/etc/crontab :盡量不要改這個系統級定義的計劃任務文件,而是自己定義,用命令crontab -e (參照格式寫,其中user-name無需再寫) - 用戶cron任務:
crontab命令
日誌:/var/log/cron ,其中記錄了計劃任務是否執行- 註意rpm -ql cronie 或者 rpn -qf /usr/bin/crontab,查看信息。然後ll /usr/bin/crontab 可以看到它有suid權限,因此用戶可以定義計劃任務。
系統cron任務:/etc/crontab
註釋行以 # 開頭
詳情參見 man 5 crontab
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * user-name command to be executed
例如:晚上9點10分運行echo命令
10 21 * wang /bin/echo "Howdy!"
時間表示法:
(1) 特定值
給定時間點有效取值範圍內的值
(2) *
給定時間點上有效取值範圍內的所有值
表示“每...”
(3) 離散取值
#,#,#
(4) 連續取值
#-#
(5) 在指定時間範圍上,定義步長
/#: #即為步長
對應時間格式
@形式 | 時間形式 |
---|---|
@reboot | Run once after reboot |
@yearly | 0 0 1 1 * |
@annually | 0 0 1 1 * |
@monthly | 0 0 1 |
@weekly | 0 0 0 |
@daily | 0 0 * |
@hourly | 0 |
示例:每3小時echo和wall命令
0 /3 centos /bin/echo “howdy”; wall “welcome to Magedu!”
系統的計劃任務:
/etc/crontab 配置文件
/etc/cron.d/ 文件夾內的配置文件
/etc/cron.hourly/ 腳本
/etc/cron.daily/ 腳本
/etc/cron.weekly/ 腳本
/etc/cron.monthly/ 腳本
anacron系統
運行計算機關機時cron不運行的任務,CentOS6以後版本取消anacron服務,由crond服務管理
對筆記本電腦、臺式機、工作站、偶爾要關機的服務器及其它不一直開機的系統很重要對很有用
- 配置文件:/etc/anacrontab,負責執行/etc/ cron.daily /etc/cron.weekly /etc/cron.monthly中系統任務
字段1:如果在這些日子裏沒有運行這些任務……
字段2:在重新引導後等待這麽多分鐘後運行它
字段3:任務識別器,在日誌文件中標識
字段4:要執行的任務
由/etc/cron.hourly/0anacron執行
當執行任務時,更新/var/spool/anacron/cron.daily文件的時間戳
管理臨時文件
CentOS7使用systemd-tmpfiles-setup服務實現
CentOS6使用/etc/cron.daily/tmpwatch定時清除臨時文件
-
配置文件:
/etc/tmpfiles.d/.conf
/run/tmpfiles.d/.conf
/usr/lib/tmpfiles/*.conf -
/usr/lib/tmpfiles.d/tmp.conf
d /tmp 1777 root root 10d
d /var/tmp 1777 root root 30d - 主要清除 /tmp (以及/usr/tmp) 和 /var/tmp 中的文件
命令:
systemd-tmpfiles –clean|remove|create configfile
用戶計劃任務
crontab命令定義
每個用戶都有專用的cron任務文件:/var/spool/cron/USERNAME
crontab命令:
crontab [-u user] [-l | -r | -e] [-i]
-l 列出所有任務
-e 編輯任務 :誰執行就是以誰為用戶來執行,因此user-name這項不用再寫。同時在執行它的時候會有一個臨時文件,執行完之後便會消除掉它。
-r 移除所有任務
-i 同-r一同使用,以交互式模式移除指定任務
-u user 僅root可運行,指定用戶管理cron任務
控制用戶執行計劃任務:
/etc/cron.{allow,deny}
總結at和crontab
- 一次性作業使用 at
- 重復性作業使用crontab
操作 | at命令 | crontab命令 |
---|---|---|
Create | at time | crontab -e |
List | at -l | crontab -l |
Details | at -c jobnum | crontab -l |
Remove | at -d jobnum | crontab -r |
Edit | N/A | crontab -e |
- 沒有被重定向的輸出會被郵寄給用戶
- root能夠修改其它用戶的作業
註意:運行結果的標準輸出和錯誤以郵件通知給相關用戶
(1) COMMAND > /dev/null
(2) COMMAND &> /dev/null
對於cron任務來講,%有特殊用途;如果在命令中要使用%,則需要轉義,或者將%放置於單引號中,則可不用轉義.如果需要%(比如date命令中),則要把它寫入腳本中,然後執行腳本即可
註意:
- at 和crontab在 測試中發現如果設置的時間小於當前時間點(比如現在時間3點,執行命令2點)則它會明天執行(即使此時把時間改為1點59分它也不會馬上執行了,因為還有日期的關系,別忘記了)需要註意這一點
- 寫入計劃任務的命令的標準輸出盡量都扔到垃圾箱裏面,因為它都會以郵件方式進行保存,如果執行的次數過多也會造成垃圾文件。所以都重定向到垃圾箱內比較好(當然 at命令可以不用這樣設置,因為它僅僅執行一次,甚至用-m 強行發送郵件判斷它是否執行)
- 腳本或者命令最好寫全路徑。
- 註意一點,如果時間格式如下所示,則代表的日子和星期並非是與的關系,而是或的關系,它表示每月的1 10 20日和每周的星期1 5 都會進行計劃任務。
- 如果非要是與的關系,則只能在後面的CMD中進行判斷了,比如下面的判斷是否是周日
30 23 1,10,20 * 1,5 CMD
30 23 1,10,20 * * [ `date +%w` -eq 0 ] && cmd
例子:計劃任務來重啟httpd服務
cat /etc/crontab
crontab -e
* * * * * /usr/bin/killall -0 httpd &> /dev/null || systemctl start httpd
crontab -l
cat /var/spool/cron/root
cat /var/log/cron
思考:
(1) 如何在秒級別運行任務?
-
-
-
-
- for min in 0 1 2; do echo "hi"; sleep 20; done
(2) 如何實現每7分鐘運行一次任務?
- for min in 0 1 2; do echo "hi"; sleep 20; done
-
-
-
sleep命令:
sleep NUMBER[SUFFIX]...
SUFFIX:
s: 秒, 默認
m: 分
h: 小時
d: 天
usleep:標準單位為1us,微秒
usleep 1000000 :此為1秒
18.系統進程和性能管理,計劃任務