戰(zhàn):從文本處理到磁盤(pán)管理的高頻命令詳解)
1. 為什么學(xué)Linux總卡在“會(huì)用但不懂”很多人學(xué)Linux都有一個(gè)共同的困惑命令背了一堆跟著教程敲了一遍當(dāng)時(shí)覺(jué)得全會(huì)了過(guò)幾天再碰又覺(jué)得手生。我也經(jīng)歷過(guò)這個(gè)階段而且時(shí)間不短。直到后來(lái)做了一次系統(tǒng)性的實(shí)戰(zhàn)整理把零散的知識(shí)點(diǎn)串成一條線才發(fā)現(xiàn)問(wèn)題不在記性而在學(xué)習(xí)方式。這套“小柏實(shí)戰(zhàn)學(xué)習(xí)Linux”系列就是圍繞真實(shí)操作場(chǎng)景來(lái)組織的。每一篇都從實(shí)際需求出發(fā)先搞清楚“要解決什么問(wèn)題”再一步步落地命令和配置。這一篇是第八講重點(diǎn)聚焦在文本處理、進(jìn)程管理、網(wǎng)絡(luò)排查和磁盤(pán)操作這四個(gè)方向。這些內(nèi)容看起來(lái)基礎(chǔ)但恰恰是日常使用頻率最高、最容易出錯(cuò)的環(huán)節(jié)。如果你已經(jīng)在用Linux但總覺(jué)得命令是死記硬背、換個(gè)環(huán)境就發(fā)蒙這一篇可以幫你把思路理清楚。如果你剛?cè)腴T(mén)跟著實(shí)操走一遍也能避開(kāi)不少我當(dāng)年踩過(guò)的坑。2. 四個(gè)高頻場(chǎng)景為什么值得花時(shí)間拆解2.1 文本處理日志排查和配置修改的日常功課Linux系統(tǒng)里幾乎所有配置都是文本文件日志也是文本。所以文本處理能力直接決定了你排查問(wèn)題的效率。很多新手只會(huì)用cat把文件全打出來(lái)日志一大就刷屏根本看不過(guò)來(lái)。真正干活的時(shí)候需要的是精確抽取、過(guò)濾、統(tǒng)計(jì)和格式化輸出。這篇里的文本處理部分用的是awk、sed、grep、sort、uniq這幾個(gè)命令的組合拳。它們各自負(fù)責(zé)一件事串聯(lián)起來(lái)就能完成從“原始日志”到“結(jié)論”的完整鏈路。2.2 進(jìn)程管理系統(tǒng)卡頓和異常排查的入口服務(wù)器卡了、CPU飆高了、某個(gè)服務(wù)掛了第一件事就是看進(jìn)程。ps只能看靜態(tài)快照top能實(shí)時(shí)刷新配合kill、nice、renice這些控制命令才能完整管理一個(gè)進(jìn)程的整個(gè)生命周期。我在實(shí)操中特別加了按線程維度排查CPU占用的小例子因?yàn)樯a(chǎn)環(huán)境里很多性能問(wèn)題都藏在多線程進(jìn)程的某個(gè)線程里只看進(jìn)程級(jí)數(shù)據(jù)往往定位不到根因。2.3 網(wǎng)絡(luò)排查服務(wù)連不上的時(shí)候靠它救命網(wǎng)絡(luò)問(wèn)題是最讓人頭疼的。域名解析對(duì)不對(duì)、端口通不通、數(shù)據(jù)包丟沒(méi)丟、路由怎么走的每層問(wèn)題都需要不同工具。ping和telnet只能做最初步的連通性測(cè)試真正深入還得靠ss、traceroute、tcpdump這些工具。2.4 磁盤(pán)操作從分區(qū)到掛載的完整流程磁盤(pán)操作屬于平時(shí)用不到、一旦要用就容錯(cuò)率很低的操作。分區(qū)表、文件系統(tǒng)、掛載點(diǎn)每一步都有講究。這篇的disk案例里我完整走了一遍“識(shí)別磁盤(pán)-分區(qū)-格式化-掛載-驗(yàn)證”的流程并且特別強(qiáng)調(diào)了數(shù)據(jù)備份的問(wèn)題。場(chǎng)景涉及命令典型痛點(diǎn)文本處理awk、sed、grep、sort、uniq日志太大、格式不統(tǒng)一進(jìn)程管理ps、top、kill、nice、reniceCPU飆高、找不到進(jìn)程網(wǎng)絡(luò)排查ping、ss、traceroute、tcpdump端口不通、連接超時(shí)磁盤(pán)操作lsblk、fdisk、mkfs、mount分區(qū)誤操作、掛載失敗這四個(gè)場(chǎng)景有一個(gè)共同特點(diǎn)都離不開(kāi)“觀察-定位-動(dòng)手-驗(yàn)證”的循環(huán)。觀察靠查看類(lèi)命令定位靠過(guò)濾和分析動(dòng)手靠控制類(lèi)命令驗(yàn)證靠再次查看。理解了這條循環(huán)遇到新工具也能快速上手。3. 文本處理三件套grep、awk、sed的配合實(shí)戰(zhàn)3.1 grep先篩行快速劃定范圍grep的核心邏輯是按行匹配模式把符合條件的行打印出來(lái)。排查日志時(shí)第一步永遠(yuǎn)是先用grep把相關(guān)行撈出來(lái)縮小范圍。假設(shè)有一個(gè)名為“app.log”的日志文件里面有大量訪問(wèn)記錄和錯(cuò)誤信息。最常見(jiàn)的操作是:grep ERROR app.log這只是最簡(jiǎn)單的用法。實(shí)際排查中更常用的是加參數(shù)grep -n ERROR app.log # 顯示行號(hào) grep -i error app.log # 忽略大小寫(xiě) grep -v DEBUG app.log # 反向匹配排除調(diào)試日志這里有個(gè)很容易忽略的點(diǎn)如果日志文件很大比如幾個(gè)GB直接用grep全量掃描會(huì)慢??梢韵劝磿r(shí)間段粗篩比如日志名按日期滾動(dòng)類(lèi)似app-20250601.log這樣的命名或者在日志里先截取某個(gè)時(shí)間窗口后再繼續(xù)處理。實(shí)際生產(chǎn)環(huán)境里日志文件基本都做了輪轉(zhuǎn)切割直接找到對(duì)應(yīng)時(shí)段的文件比在一個(gè)大文件里硬翻效率高得多。3.2 awk取列和統(tǒng)計(jì)結(jié)構(gòu)化整理數(shù)據(jù)grep篩完行之后很多場(chǎng)景需要進(jìn)一步提取特定列。awk就是干這個(gè)的。它按分隔符把每一行拆成字段默認(rèn)按空格或制表符分割用$1、$2……引用對(duì)應(yīng)列。接著上面的場(chǎng)景假設(shè)日志格式是“時(shí)間 IP 請(qǐng)求路徑 狀態(tài)碼”想找出所有返回5xx錯(cuò)誤的請(qǐng)求路徑awk $4 ~ /^5[0-9][0-9]$/ {print $3, $4} app.log這條命令的意思是第四列以5開(kāi)頭、后面跟兩位數(shù)字的把第三列和第四列打出來(lái)。這里$4是狀態(tài)碼$3是請(qǐng)求路徑。awk真正的威力在于它是一門(mén)小型編程語(yǔ)言支持變量、循環(huán)、條件判斷。比如統(tǒng)計(jì)每個(gè)IP的請(qǐng)求次數(shù)awk {count[$2]} END {for (ip in count) print ip, count[ip]} app.log | sort -k2 -nr | head這條命令是awk和sort、head的組合。count數(shù)組統(tǒng)計(jì)第二列每個(gè)IP的出現(xiàn)次數(shù)END塊在讀完所有行之后執(zhí)行把統(tǒng)計(jì)結(jié)果打印出來(lái)再交給sort按第二列數(shù)值從大到小排最后取前10條。這就是把“原始日志”變成“結(jié)論”的典型過(guò)程。注意awk里的數(shù)組下標(biāo)如果列里包含重復(fù)值會(huì)被折疊統(tǒng)計(jì)所以這一步之前最好確認(rèn)列內(nèi)容是否符合預(yù)期。我遇到過(guò)日志中IP列偶發(fā)為空的情況統(tǒng)計(jì)結(jié)果里多出一個(gè)空字符串的“IP”排查了半小時(shí)才發(fā)現(xiàn)是臟數(shù)據(jù)。3.3 sed精準(zhǔn)替換修改配置不用開(kāi)編輯器sed按行處理文本可以做替換、刪除、插入。最常用的替換場(chǎng)景是批量改配置。比如把配置文件里所有監(jiān)聽(tīng)8080端口的配置改成9090sed -i s/8080/9090/g nginx.conf這個(gè)命令的讀法是-i表示直接修改文件s表示替換8080是查找模式9090是替換內(nèi)容g表示全局替換不只是在每行第一次出現(xiàn)時(shí)替換。有幾個(gè)坑要提醒-i參數(shù)在修改前最好先不加直接跑一遍看輸出對(duì)不對(duì)確認(rèn)無(wú)誤再加-i真正寫(xiě)回文件。如果配置文件里有多種8080含義比如注釋里也提到了8080建議先grep確認(rèn)所有出現(xiàn)位置再?zèng)Q定替換范圍。sed的正則用的是基礎(chǔ)正則和grep的擴(kuò)展正則、awk的正則都有細(xì)微差別同樣一個(gè)表達(dá)式在不同工具里可能含義不同。比如在基礎(chǔ)正則里是普通字符要加反斜杠轉(zhuǎn)義為\才表示“一個(gè)或多個(gè)”。3.4 sort、uniq做去重統(tǒng)計(jì)數(shù)據(jù)收口靠它倆sort給行排序uniq去除相鄰重復(fù)行。注意uniq只能去重相鄰的重復(fù)行所以必須先sort再u(mài)niq這倆幾乎總是連著用。日志去重統(tǒng)計(jì)的標(biāo)準(zhǔn)三連sort access.log | uniq -c | sort -rn | head -20先排序再去重并顯示每行重復(fù)次數(shù)-c再按次數(shù)從大到小排列-rn最后取前20條。這個(gè)組合在分析日志里“哪些錯(cuò)誤反復(fù)出現(xiàn)”時(shí)非常高效。4. 進(jìn)程管理的實(shí)操?gòu)?fù)盤(pán)4.1 ps和top靜態(tài)與動(dòng)態(tài)結(jié)合看ps -ef和ps aux是日常查看進(jìn)程最常用的兩條命令。它們的區(qū)別在于輸出格式不同前者偏向顯示父子關(guān)系和完整命令行后者偏向顯示CPU和內(nèi)存占用。排查CPU飆高的標(biāo)準(zhǔn)流程我一般這樣走top -b -n 1這個(gè)命令用批處理模式跑一次并退出避免動(dòng)態(tài)刷新帶來(lái)的干擾。在腳本或排查記錄時(shí)比直接交互式top更好用。如果看到某個(gè)進(jìn)程CPU占用率接近100%再深入一步看它的線程分布top -H -p PID-H參數(shù)按線程展示-p指定進(jìn)程ID。這一步非常關(guān)鍵因?yàn)镴ava、Python這類(lèi)多線程應(yīng)用進(jìn)程整體CPU高但具體是哪個(gè)線程在“燒”CPU必須切到線程級(jí)才看得清。我曾經(jīng)排查過(guò)一個(gè)服務(wù)偶發(fā)卡頓進(jìn)程CPU看起來(lái)才60%但切到線程視圖后立刻看到一個(gè)線程占用打滿(mǎn)最后定位到是某個(gè)異步任務(wù)的死循環(huán)。4.2 kill與其他信號(hào)不是只有強(qiáng)殺kill默認(rèn)發(fā)送TERM信號(hào)15請(qǐng)求進(jìn)程正常退出。如果進(jìn)程不響應(yīng)才會(huì)用到KILL信號(hào)9強(qiáng)制終止。除這兩個(gè)之外常見(jiàn)信號(hào)還有信號(hào)數(shù)值作用HUP1掛斷常用于重讀配置文件INT2鍵盤(pán)中斷等價(jià)于CtrlCTERM15默認(rèn)終止信號(hào)進(jìn)程可自行清理KILL9強(qiáng)制終止不可捕獲不可忽略STOP19暫停進(jìn)程不終止CONT18繼續(xù)已暫停的進(jìn)程實(shí)際運(yùn)維中改完nginx配置后讓配置立即生效不需要重啟進(jìn)程只需要發(fā)送HUP信號(hào)kill -HUP [nginx的PID]這個(gè)操作的原理是nginx主進(jìn)程收到HUP信號(hào)后會(huì)重新讀取配置文件并拉起新的worker進(jìn)程比stop再start快而且不會(huì)中斷正在處理的連接。這個(gè)技巧比直接重啟優(yōu)雅得多也是老運(yùn)維和新人之間一個(gè)很小的分水嶺。4.3 nice和renice讓進(jìn)程按優(yōu)先級(jí)跑Linux的CPU調(diào)度是按優(yōu)先級(jí)搶占的優(yōu)先級(jí)數(shù)值范圍是-20到19數(shù)值越小優(yōu)先級(jí)越高。普通用戶(hù)只能調(diào)高nice值降低優(yōu)先級(jí)只有root能調(diào)低nice值提高優(yōu)先級(jí)。啟動(dòng)一個(gè)新任務(wù)時(shí)指定優(yōu)先級(jí)nice -n 10 ./backup_script.sh對(duì)已經(jīng)運(yùn)行的進(jìn)程調(diào)整優(yōu)先級(jí)renice -n 10 -p PID一個(gè)典型場(chǎng)景是白天業(yè)務(wù)高峰期不要跑全量備份腳本但如果非要跑就把它nice調(diào)高一些讓它把CPU讓給業(yè)務(wù)進(jìn)程。我當(dāng)時(shí)的實(shí)操環(huán)境里跑過(guò)一次全量數(shù)據(jù)導(dǎo)出把進(jìn)程nice設(shè)為10之后業(yè)務(wù)側(cè)高負(fù)載時(shí)的響應(yīng)延遲明顯比默認(rèn)優(yōu)先級(jí)的情況好。這個(gè)細(xì)節(jié)在高負(fù)載服務(wù)器上非常實(shí)用。5. 網(wǎng)絡(luò)排查與磁盤(pán)操作的踩坑實(shí)錄5.1 從ping到traceroute層層逼近問(wèn)題點(diǎn)ping測(cè)通不代表網(wǎng)絡(luò)“沒(méi)問(wèn)題”它只能說(shuō)明ICMP協(xié)議在目標(biāo)主機(jī)和源主機(jī)之間可達(dá)。很多服務(wù)器禁ping所以ping不通不一定服務(wù)不可用。判斷一個(gè)服務(wù)是否正常關(guān)鍵要看TCP端口是否連通。我習(xí)慣用ss命令替代老舊的netstat前者更快輸出也更清晰ss -ltn這條命令列出所有監(jiān)聽(tīng)的TCP端口。-l是只看監(jiān)聽(tīng)狀態(tài)-t是TCP協(xié)議-n是不解析域名直接顯示IP端口。如果能看到目標(biāo)端口處于LISTEN狀態(tài)說(shuō)明本機(jī)服務(wù)正常。如果本機(jī)端口正常但外部連接失敗大概率是防火墻或云安全組攔截了。路由追蹤用traceroutetraceroute -n 目標(biāo)IP它逐跳打印從本機(jī)到目標(biāo)IP經(jīng)過(guò)的路由節(jié)點(diǎn)。如果某一段出現(xiàn)星號(hào)或者延遲暴漲說(shuō)明這一段網(wǎng)絡(luò)有擁塞或丟包。注意traceroute輸出里的每一跳代表一個(gè)路由器接口不代表一臺(tái)獨(dú)立機(jī)器。5.2 tcpdump抓包看真相網(wǎng)絡(luò)排查的最后一步往往要用tcpdump抓包確認(rèn)數(shù)據(jù)包是否到達(dá)本機(jī)、是否發(fā)出響應(yīng)。它需要root權(quán)限非常強(qiáng)大也容易產(chǎn)生大量輸出所以抓包必須指定過(guò)濾條件。最常見(jiàn)的抓包方式tcpdump -i eth0 port 8080 -c 100-i指定網(wǎng)卡port指定端口-c限定抓取100個(gè)包后自動(dòng)停止。如果要保存抓包結(jié)果以便后續(xù)用圖形化工具分析加-w參數(shù)tcpdump -i eth0 port 8080 -w /tmp/capture.pcap抓完的pcap文件可以用Wireshark打開(kāi)分析。注意tcpdump抓包時(shí)如果流量本身就很大不加過(guò)濾條件會(huì)直接打滿(mǎn)磁盤(pán)。我第一次實(shí)操時(shí)忘記加-c限制抓了十幾分鐘磁盤(pán)空間告急緊急用CtrlC終止才算沒(méi)把系統(tǒng)搞掛。養(yǎng)成“先加過(guò)濾條件、再加包數(shù)量限制”的習(xí)慣能避免很多麻煩。5.3 磁盤(pán)分區(qū)和掛載的完整流程虛擬機(jī)里新增了一塊磁盤(pán)系統(tǒng)里看不到第一步要確認(rèn)系統(tǒng)是否識(shí)別到lsblklsblk列出所有塊設(shè)備包括磁盤(pán)、分區(qū)、掛載點(diǎn)和容量。如果新磁盤(pán)出現(xiàn)了但沒(méi)有任何分區(qū)接著用fdisk分區(qū)fdisk /dev/sdb進(jìn)入fdisk交互界面后按n新建分區(qū)按p選主分區(qū)后續(xù)一路默認(rèn)值即可最后按w寫(xiě)入分區(qū)表。分區(qū)完成后分區(qū)表里會(huì)出現(xiàn)類(lèi)似sdb1的條目。接下來(lái)格式化mkfs.ext4 /dev/sdb1創(chuàng)建ext4文件系統(tǒng)。其他常用格式還有xfsCentOS/RHEL默認(rèn)、btrfs等按發(fā)行版習(xí)慣選擇。格式化之后才能掛載mkdir /data mount /dev/sdb1 /data掛載后還要讓開(kāi)機(jī)自動(dòng)掛載就得改/etc/fstab文件。手動(dòng)掛載和開(kāi)機(jī)掛載必須保持一致否則重啟后目錄是空的。修改fstab的關(guān)鍵一行/dev/sdb1 /data ext4 defaults 0 0寫(xiě)完fstab后強(qiáng)烈建議先驗(yàn)證一遍mount -a這條命令會(huì)重新讀取fstab并掛載其中所有條目。如果fstab寫(xiě)錯(cuò)了mount -a會(huì)直接報(bào)錯(cuò)可以在重啟前及時(shí)修正。這個(gè)驗(yàn)證步驟能避免一次服務(wù)器重啟后找不到文件系統(tǒng)的慘劇。注意云服務(wù)器里的數(shù)據(jù)盤(pán)某些場(chǎng)景建議用文件系統(tǒng)的UUID而不是/dev/sdX這種設(shè)備名來(lái)掛載。因?yàn)樵O(shè)備名在系統(tǒng)重啟后可能變化比如sdb變成sdc但UUID不會(huì)變。用blkid命令可以查到每個(gè)文件系統(tǒng)的UUIDfstab里寫(xiě)UUID更穩(wěn)。5.4 我踩過(guò)的坑格式化前沒(méi)確認(rèn)盤(pán)符新磁盤(pán)的分區(qū)、格式化、掛載這套流程本身不難真正危險(xiǎn)的是在執(zhí)行命令時(shí)找錯(cuò)了磁盤(pán)。我實(shí)操時(shí)遇到過(guò)一個(gè)很驚險(xiǎn)的瞬間明明以為在操作/dev/sdc后來(lái)用lsblk復(fù)查才發(fā)現(xiàn)系統(tǒng)里還掛著一個(gè)數(shù)據(jù)盤(pán)/dev/sdb兩者塊大小和容量極其相似。從那以后我養(yǎng)成一個(gè)習(xí)慣任何磁盤(pán)操作前先跑lsblk和blkid把設(shè)備名、容量、已有分區(qū)、掛載點(diǎn)全部確認(rèn)一遍再用df -h復(fù)查一遍現(xiàn)有磁盤(pán)狀態(tài)確保自己不會(huì)把已有數(shù)據(jù)的磁盤(pán)格式化掉。磁盤(pán)操作的容錯(cuò)率極低多花兩分鐘確認(rèn)對(duì)比可能的災(zāi)難性損失非常劃算。6. 日志分析組合拳一個(gè)完整案例走查6.1 場(chǎng)景描述和原始日志為把前面的命令串起來(lái)我在本機(jī)搭了一個(gè)模擬場(chǎng)景。有一個(gè)訪問(wèn)日志文件access.log內(nèi)容格式是“時(shí)間 客戶(hù)端IP 請(qǐng)求方法 路徑 狀態(tài)碼 耗時(shí)ms”我拿它做了完整分析。日志內(nèi)容大約幾百行其中混著正常請(qǐng)求和錯(cuò)誤請(qǐng)求。先看文件整體情況wc -l access.log假設(shè)輸出是342行說(shuō)明日志不大可以直接處理。如果日志有幾十萬(wàn)行就要謹(jǐn)慎設(shè)計(jì)命令避免一次掃描太久。6.2 先整體后細(xì)節(jié)狀態(tài)碼分布第一步先看整體狀態(tài)碼分布awk {print $5} access.log | sort | uniq -c | sort -rn這里$5是狀態(tài)碼字段。輸出結(jié)果會(huì)像這樣280 200 42 404 12 500 8 502看到200占絕大多數(shù)但500和502加起來(lái)有20條說(shuō)明服務(wù)確實(shí)存在不穩(wěn)定情況。這一步的價(jià)值在于不需要逐條看日志就能對(duì)系統(tǒng)整體健康狀況有個(gè)基本判斷。6.3 定位錯(cuò)誤集中在哪些路徑上接下來(lái)精確定位哪些請(qǐng)求路徑返回5xx錯(cuò)誤awk $5 500 {print $3, $5, $6} access.log | sort | uniq -c | sort -rn這條命令把狀態(tài)碼大于等于500的行拿出來(lái)打印請(qǐng)求方法、狀態(tài)碼、耗時(shí)然后統(tǒng)計(jì)排序。實(shí)際操作中大多錯(cuò)誤路徑會(huì)集中在兩三個(gè)接口上這樣排查方向就很明確了。如果還懷疑錯(cuò)誤是否隨時(shí)間集中出現(xiàn)可以加時(shí)間段分析awk $5 500 {print $1} access.log | cut -c12-19 | sort | uniq -c這里的$1是時(shí)間字段cut -c12-19截取出時(shí)分秒部分。通過(guò)統(tǒng)計(jì)各時(shí)間段的錯(cuò)誤條數(shù)能看出錯(cuò)誤是持續(xù)存在還是集中在某個(gè)時(shí)間窗口后者往往指向定時(shí)任務(wù)或流量高峰。6.4 綜合判斷加驗(yàn)證分析完日志接著用ss確認(rèn)相關(guān)服務(wù)端口狀態(tài)ss -ltn | grep 8080然后通過(guò)進(jìn)程列表確認(rèn)服務(wù)進(jìn)程在跑ps aux | grep [服務(wù)名]這里多提一句grep加方括號(hào)的寫(xiě)法grep [服]務(wù)名是為了避免grep進(jìn)程本身匹配到自己。如果不加方括號(hào)ps輸出里的那一行g(shù)rep命令也會(huì)被自己匹配到干擾判斷。這是很多教程不會(huì)特意提的小細(xì)節(jié)但實(shí)際排查時(shí)很實(shí)用。至此這輪日志排查就完成了一個(gè)閉環(huán)從原始日志到狀態(tài)碼分布從錯(cuò)誤集中路徑到時(shí)間窗口再結(jié)合端口和進(jìn)程狀態(tài)基本能確定問(wèn)題方向。7. 高頻報(bào)錯(cuò)和排查速查實(shí)操過(guò)程中一定會(huì)遇到報(bào)錯(cuò)這里把我遇到過(guò)且典型的幾個(gè)列出來(lái)方便對(duì)照排查。7.1 “Permission denied”類(lèi)文件或目錄權(quán)限不足。先用ls -l看權(quán)限位再用id確認(rèn)當(dāng)前用戶(hù)是否屬于目標(biāo)文件的所有者或所屬組。ls -l /path/to/file id如果確認(rèn)權(quán)限沒(méi)問(wèn)題但還是拒絕訪問(wèn)檢查SELinux是否攔截用getenforce查看狀態(tài)。SELinux開(kāi)啟且策略不匹配時(shí)即使權(quán)限位完全正確服務(wù)也可能無(wú)法讀取文件。這種情況在CentOS系系統(tǒng)上尤其常見(jiàn)。7.2 “command not found”類(lèi)命令不在PATH路徑里或者包未安裝。先which看命令是否存在再用包管理器安裝。which tcpdump無(wú)輸出說(shuō)明沒(méi)裝CentOS系用yum install tcpdumpDebian系用apt install tcpdump。注意某些基礎(chǔ)命令在不同發(fā)行版里歸屬不同包比如ifconfig在較新系統(tǒng)中可能不存在需要改用ip命令。7.3 “Address already in use”類(lèi)端口被占用。用ss -ltn找到占用端口的進(jìn)程再?zèng)Q定是kill進(jìn)程還是換端口。ss -ltnp | grep 8080-p參數(shù)會(huì)顯示對(duì)應(yīng)進(jìn)程PID和名稱(chēng)。拿到PID后用ps確認(rèn)是什么程序確認(rèn)可以停止后kill掉。如果端口被系統(tǒng)隨機(jī)分配給某個(gè)內(nèi)核線程占用排查起來(lái)更麻煩但多數(shù)場(chǎng)景就是某個(gè)舊進(jìn)程沒(méi)退干凈。7.4 系統(tǒng)命令超時(shí)或無(wú)響應(yīng)這種情況多發(fā)生在負(fù)載過(guò)高時(shí)。先看load averageuptime三列數(shù)字分別代表1分鐘、5分鐘、15分鐘平均負(fù)載。如果15分鐘負(fù)載都比CPU核數(shù)高很多說(shuō)明系統(tǒng)長(zhǎng)時(shí)間處于高負(fù)載狀態(tài)。此時(shí)再配合top看具體是哪個(gè)進(jìn)程吃資源確認(rèn)后用kill或renice處理。報(bào)錯(cuò)場(chǎng)景檢查命令處理思路權(quán)限拒絕ls -l、id、getenforce權(quán)限位、用戶(hù)歸屬、SELinux命令找不到which確認(rèn)是否存在按發(fā)行版安裝端口被占用ss -ltnp確認(rèn)進(jìn)程停止或換端口系統(tǒng)無(wú)響應(yīng)uptime、top看負(fù)載定位吃資源的進(jìn)程8. 自定義腳本串起日常巡檢8.1 腳本思路和核心命令組合把日志分析、進(jìn)程檢查、磁盤(pán)查詢(xún)整合成一個(gè)快速巡檢腳本是我覺(jué)得實(shí)戰(zhàn)價(jià)值最大的一步。這個(gè)腳本不復(fù)雜但能一次性輸出系統(tǒng)關(guān)鍵狀態(tài)。腳本思路分四塊系統(tǒng)負(fù)載、內(nèi)存余量、磁盤(pán)占用、監(jiān)聽(tīng)端口。核心命令組合如下#!/bin/bash echo 系統(tǒng)負(fù)載 uptime echo 內(nèi)存 free -h echo 磁盤(pán) df -h echo 監(jiān)聽(tīng)端口 ss -ltn這里每條命令的輸出都經(jīng)過(guò)格式化方便快速閱讀。腳本可以保存在/usr/local/bin/下并加執(zhí)行權(quán)限后續(xù)直接調(diào)用名字就能跑。注意腳本里的命令路徑建議用絕對(duì)路徑或者確保PATH環(huán)境變量在非交互式Shell下包含了這些命令路徑。cron執(zhí)行腳本時(shí)PATH環(huán)境變量往往比交互式Shell精簡(jiǎn)很多直接寫(xiě)命令名有時(shí)會(huì)找不到。用which uptime查到的絕對(duì)路徑寫(xiě)進(jìn)腳本更穩(wěn)。8.2 保存日志和告警日常巡檢光打印到屏幕不夠還要留痕??梢园演敵鲋囟ㄏ虻饺罩疚募⒓訒r(shí)間戳echo $(date %Y-%m-%d %H:%M:%S) /var/log/syscheck.log uptime /var/log/syscheck.log free -h /var/log/syscheck.log如果希望異常時(shí)提醒可以對(duì)關(guān)鍵指標(biāo)做判斷。比如磁盤(pán)使用率超過(guò)90%時(shí)輸出成警告disk_usage$(df / | awk NR2 {print $5} | sed s/%//) if [ $disk_usage -gt 90 ]; then echo 磁盤(pán)使用率過(guò)高: $disk_usage% /var/log/syscheck.log fi這里的邏輯是df /取根分區(qū)使用率awk取第五列的百分比sed把百分號(hào)去掉然后再和90做數(shù)值比較。這個(gè)腳本可以放到crontab里定時(shí)執(zhí)行實(shí)現(xiàn)每天固定時(shí)間的自動(dòng)巡檢。8.3 定時(shí)任務(wù)注意事項(xiàng)配置croncrontab -e添加一行0 2 * * * /usr/local/bin/syscheck.sh這樣每天凌晨2點(diǎn)執(zhí)行一次巡檢。放在凌晨是為了避開(kāi)業(yè)務(wù)高峰期避免腳本本身的系統(tǒng)資源占用影響業(yè)務(wù)。我的體會(huì)是這類(lèi)巡檢腳本不需要很復(fù)雜關(guān)鍵是能把高頻檢查項(xiàng)固化下來(lái)。真遇到問(wèn)題的時(shí)候先跑一遍巡檢腳本拿到整體狀態(tài)再針對(duì)異常項(xiàng)深入排查效率遠(yuǎn)比一條條敲命令高得多。9. 一些值得長(zhǎng)期堅(jiān)持的習(xí)慣實(shí)操多了以后我發(fā)現(xiàn)真正拉開(kāi)效率差距的不是某個(gè)神級(jí)技巧而是一系列小習(xí)慣。第一命令先想清楚再執(zhí)行尤其是刪除、格式化、覆蓋這類(lèi)不可逆操作。Linux命令一旦執(zhí)行沒(méi)有“撤銷(xiāo)”按鍵。我會(huì)在關(guān)鍵命令前先跑一遍dry run或先echo打印命令本身確認(rèn)無(wú)誤再真正執(zhí)行。第二每學(xué)到一條新命令隨手記下適用場(chǎng)景和注意事項(xiàng)而不是只記命令拼寫(xiě)。命令拼寫(xiě)可以查手冊(cè)使用場(chǎng)景和踩過(guò)的坑往往查不到。我自己維護(hù)了一個(gè)Markdown筆記按“文本處理”“進(jìn)程管理”“網(wǎng)絡(luò)排查”分類(lèi)遇到問(wèn)題先翻筆記已經(jīng)解決過(guò)的問(wèn)題不再需要重新排查一遍。第三保持“驗(yàn)證”的習(xí)慣。任何修改配置的操作執(zhí)行后都要用查看類(lèi)命令確認(rèn)生效。改完fstab跑mount -a改完nginx配置kill -HUP后再用curl驗(yàn)證響應(yīng)改完防火墻規(guī)則后用ss或telnet驗(yàn)證端口仍然正常。驗(yàn)證這一步看似多余實(shí)際上能擋住大部分低級(jí)錯(cuò)誤。第四日志和輸出要留痕。日常排查的現(xiàn)場(chǎng)輸出如果數(shù)據(jù)量大不要只靠肉眼翻養(yǎng)成輸出到文件再分析的習(xí)慣。很多問(wèn)題需要對(duì)比前后變化留有原始輸出就是留下了對(duì)比的基準(zhǔn)線。第五模板化。像巡檢腳本這種重復(fù)性工作一定要模板化、腳本化。人總會(huì)疲勞腳本不會(huì)。把判斷邏輯寫(xiě)進(jìn)腳本既統(tǒng)一了檢查口徑也避免了臨場(chǎng)手忙腳亂。