
1. 這篇“Linux(11)(下)”到底在解決什么問題1.1 從“會敲命令”到“能管機器”運維視角的Linux進階路徑如果你能看到這里說明你已經不是那個對著終端發(fā)怵的新手了。前面十篇內容我們聊過基礎命令、文件權限、進程管理、網絡配置甚至可能手寫過幾個簡單的Shell腳本。但現(xiàn)實中的Linux學習曲線有個很尷尬的斷層你跟著教程敲完了所有命令感覺自己“會了”可一旦真正需要你獨自去管理一臺生產服務器你會發(fā)現(xiàn)腦子里全是零散的碎片。這篇“Linux(11)(下)”系列文章的定位非常明確把那些零散的碎片拼成一張可以落地的運維地圖。它不再糾結于單個命令怎么用而是聚焦于“場景”和“決策”。舉個例子你懂chmod和useradd但你真的知道一個多人在用的服務器上權限應該怎么分配才既安全又不影響協(xié)作效率嗎你懂df -h但磁盤真的滿了的時候你知道該按什么順序排查才能最快定位到那個占滿空間的元兇嗎之所以把這一篇放在第11篇的下半部分是因為越往后的內容越接近生產環(huán)境的真實復雜度。前面的知識是磚塊這一篇要教你怎么用這些磚塊砌墻。它解決的核心問題是當系統(tǒng)不再是你學習用的虛擬機而是承載著實際業(yè)務的服務器時你的操作習慣、排查思路、故障應對方式必須完成一次從“實驗心態(tài)”到“工程心態(tài)”的轉變。1.2 這一篇覆蓋的高頻運維場景清單很多朋友學Linux容易陷入一個誤區(qū)越學越偏門天天研究那些一輩子都用不上的冷門命令。作為經歷過不少線上故障的從業(yè)者我建議你把精力集中在真正決定系統(tǒng)穩(wěn)定性的事情上。這一篇“Linux(11)(下)”選擇的內容全部來自我在實際工作中反復用到的高頻場景。大致可以分為六個方向用戶與權限的規(guī)范化管理、存儲的規(guī)劃與故障恢復、服務托管與開機自啟、網絡與防火墻排查、日志分析與故障定位、自動化腳本與巡檢。這六個方向基本覆蓋了一臺Linux服務器從日常維護到出事?lián)尵鹊耐暾窂?。你會發(fā)現(xiàn)這里面幾乎沒有炫技的內容全是實打實的“保命”技能。如果這一篇你能吃透去面試中小型公司的運維或后端開發(fā)崗位至少技術面聊到Linux這塊時不會心虛。我把每一塊的思路拆開放在后面幾章詳細展開。每一章都會遵循一個邏輯先告訴你為什么需要這么做再給你可以直接抄的實操步驟最后把我踩過的坑同步給你。有些坑官方文檔里不會寫但你在生產環(huán)境里大概率會碰到。2. 用戶與權限管理別再頂著root滿世界跑了2.1 最小權限原則下的用戶與組設計先用一個場景問問你如果你剛接手一臺服務器發(fā)現(xiàn)所有人都在用root干活你會怎么做直接改掉所有人的權限恐怕不行業(yè)務會受影響。繼續(xù)留著風險太高一旦賬號泄露整個系統(tǒng)等于裸奔。正確做法是引入一套可落地的用戶和組規(guī)劃?;驹瓌t很簡單能不用root就不用root能不給權限就不給權限。具體到實操我會先把業(yè)務角色梳理清楚。比如一臺應用服務器上可能有這幾個角色應用部署人員、日志查看人員、備份執(zhí)行人員。不同角色需要的權限完全不同。我的常用方案是創(chuàng)建三個組appdeploy應用部署組、logviewer日志查看組、backup_ops備份操作組。然后按需創(chuàng)建用戶并加入對應組。關鍵在于給組賦予合理的文件權限而不是直接給用戶授權。比如應用部署目錄/opt/myapp歸屬為appdeploy組組權限設為rwxrws---這樣組內成員可以部署更新但其他人一丁點權限都沒有。日志目錄同理logviewer組的成員只有r-x權限能看不能改。這套設計的好處在于人員變動時你只需要調整用戶的組關系不用滿服務器去改文件權限。新員工入職加組離職移組十分鐘搞定。我曾經見過一個團隊因為權限設計不合理每次人員變動都要改幾十個目錄的屬主改完之后還提心吊膽生怕哪里漏了。用組來管理權限是運維生涯中最不該省的那一步。2.2 sudo授權與特殊權限位的實戰(zhàn)用法有了用戶和組接下來要解決“有些操作確實需要臨時提權”的問題。sudo在這里就是唯一推薦路徑。我見過不少人直接給用戶加了ALL(ALL) ALL這本質上等于還是root橫行只是穿了件馬甲。更好的做法是精確到命令級別。舉個例子我要讓logviewer組的成員能重啟某個特定的應用服務但不給他們任何shell管理權限。在/etc/sudoers.d/下新建一個文件寫入%logviewer ALL(ALL) NOPASSWD: /usr/bin/systemctl restart myapp注意我用了NOPASSWD因為在自動化腳本里跑sudo不需要交互輸入密碼這能省掉很多麻煩。但代價是任何拿到這個用戶密碼的人都能直接重啟該服務所以授權命令一定要窄能精確到服務名絕不授權通配符。另外千萬別把vim這類可以執(zhí)行shell的編輯器授權給普通用戶否則他可以借編輯器的shell功能直接拿到root權限。這條坑我很多年前就踩過。再說說特殊權限位。setuid和setgid這兩個東西在日常運維里必須慎用。chmod us設置setuid后無論誰執(zhí)行這個程序都會以文件屬主的身份運行典型例子就是/usr/bin/passwd。但如果你把一個bash腳本設置成setuid那基本等于把root鑰匙掛在門口。我的建議是生產環(huán)境上不要自己創(chuàng)建任何setuid程序現(xiàn)有的系統(tǒng)文件也定期檢查一遍用下面的命令找出所有帶特殊權限位的文件find / -perm -4000 -o -perm -2000 2/dev/null檢查輸出結果凡是你沒見過的、不在系統(tǒng)標準列表里的都要查明來源。安全這個東西說白了就是習慣問題每次登錄服務器先花一分鐘看看有沒有異常遠好過出事了再追。2.3 權限排查的一個典型翻車現(xiàn)場聊一個我早年間實際遇到的場景方便你理解權限設計為什么重要。當時某團隊反映他們寫的日志文件總是無法被另一個模塊讀取兩邊都在喊冤叫屈排查了半天發(fā)現(xiàn)是文件創(chuàng)建時的umask出了問題。進程以某個用戶身份啟動默認的umask值是0027創(chuàng)建出來的文件自然就是這個權限屬主能讀寫、組只能讀、其他人一律拒絕。而讀取方恰好在“其他人”這個范圍里。這類問題的本質不是某個人的操作失誤而是整個系統(tǒng)的權限策略沒有統(tǒng)一設計。后來我給系統(tǒng)里的服務進程統(tǒng)一設置了啟動環(huán)境里的umask值并且明確要求所有應用日志文件在寫入前必須顯式設置權限掩碼不允許依賴默認值。從那以后這類跨進程讀寫失敗的問題就基本絕跡了。所以這里給你一個建議遇到“文件讀不到”“目錄進不去”的報錯第一反應不是去改目標文件的權限而是去想清楚整個讀寫鏈路涉及哪幾個用戶、哪幾個進程、各自的權限范圍是什么。揪出鏈路中權限最小的一環(huán)往往才是真正的病灶。3. 存儲管理進階LVM規(guī)劃與文件系統(tǒng)修復3.1 為什么我強烈建議生產環(huán)境用LVM“分區(qū)不夠用了怎么辦”大概是我在技術交流群里看到頻率最高的問題之一。如果你在裝系統(tǒng)時用了傳統(tǒng)的物理分區(qū)方案數(shù)據(jù)盤滿了之后擴容量要么得搬家要么得用growpart這類工具在線折騰無論哪種都夠喝一壺的。而如果你一開始就采用了LVM邏輯卷管理擴容就是一條命令的事。LVM的基本邏輯可以這樣理解你把物理硬盤先聲明為物理卷PV然后像搭積木一樣把多個物理卷合并成一個卷組VG之后在卷組上切出任意大小的邏輯卷LV給系統(tǒng)用。這就好比你先買了一塊地皮物理卷把相鄰幾塊地合在一起形成開發(fā)區(qū)卷組然后按需劃分幾塊地分別蓋樓邏輯卷。生產環(huán)境中我?guī)缀跛械臄?shù)據(jù)盤都會用LVM。理由很簡單未來的擴容、縮容、快照都需要它。比如某業(yè)務系統(tǒng)的數(shù)據(jù)目錄最初分配了100GB用了半年達到85%這時候你不需要重裝系統(tǒng)只需要加一塊新硬盤擴展卷組然后再把邏輯卷擴大文件系統(tǒng)也會跟著變大。整個過程對業(yè)務幾乎是平滑的不會產生長時間停機。還有一點容易被忽略LVM的快照功能在數(shù)據(jù)庫備份場景里極其好用。通過LVM快照可以在秒級生成一個一致性的數(shù)據(jù)鏡像然后基于鏡像做備份數(shù)據(jù)庫本身幾乎無感知。這比拿mysqldump去鎖表導數(shù)據(jù)優(yōu)雅太多了。3.2 從零構建一個LVM卷組并動態(tài)擴容具體操作我之前在文章里提過一次這里再完整走一遍流程。假設新加了一塊硬盤/dev/sdb想把它全部用于LVM。首先創(chuàng)建物理卷pvcreate /dev/sdb然后創(chuàng)建卷組命名隨意比如vg_datavgcreate vg_data /dev/sdb接著創(chuàng)建邏輯卷比如我要劃一個200GB的邏輯卷lvcreate -L 200G -n lv_web vg_data最后格式化并掛載mkfs.xfs /dev/vg_data/lv_web mkdir /data/web mount /dev/vg_data/lv_web /data/web為了讓重啟后還能掛載還需要在/etc/fstab里寫一條記錄這里我強烈建議用UUID而不是設備路徑因為設備名在重啟后可能會變化。用blkid命令查出邏輯卷的UUID然后這樣寫UUIDxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /data/web xfs defaults 0 0過了幾個月200GB不夠了。假設你模塊里還剩了空間一條命令擴容邏輯卷lvextend -L 50G /dev/vg_data/lv_web如果用的是xfs文件系統(tǒng)接著執(zhí)行xfs_growfs /data/web如果用的是ext4則是resize2fs /dev/vg_data/lv_web擴容完成后用df -h確認一下你就會看到容量已經悄悄變大了。整個過程不需要重啟不需要卸載分區(qū)。我這里想強調一個細節(jié)很多人在擴容時只執(zhí)行了lvextend忘了擴展文件系統(tǒng)然后跑來問“為什么df沒變化”。其實邏輯卷和文件系統(tǒng)是兩層概念邏輯卷變大了文件系統(tǒng)如果還保持原樣系統(tǒng)自然不認賬。像我上面寫的順序先擴邏輯卷再擴文件系統(tǒng)一步都不能少。3.3 文件系統(tǒng)損壞時的應急處理流程談及文件系統(tǒng)修復必須先立個規(guī)矩任何修復操作的前提都是先卸載分區(qū)絕不允許在掛載狀態(tài)下用fsck去修。原因很簡單掛載狀態(tài)下文件系統(tǒng)還在被內核持續(xù)寫入你一邊修復它一邊改數(shù)據(jù)只會破壞得更厲害。應急流程應該是這樣的。首先確認故障表現(xiàn)是啟動時報錯還是運行中df看到異?;蛘遜mesg里刷滿了I/O錯誤。然后立即對數(shù)據(jù)盤做只讀掛載嘗試或者干脆先不掛載。接著用fsck做檢查umount /data/web fsck -y /dev/vg_data/lv_web-y參數(shù)的意思是自動回答yes對重要數(shù)據(jù)盤建議先跑一遍無-y的檢查模式看清楚報告內容再決定。常見的結果有這么幾類clean表示文件系統(tǒng)沒有一致性問題直接掛載即可recover表示修復了一些臟數(shù)據(jù)塊modify表示做了結構性修復。如果輸出里出現(xiàn)corrupt這類字樣或者修復過程非常耗時就不要再強行加載了該考慮從備份恢復數(shù)據(jù)。備份這件事我在任何一篇Linux相關的文章里都會提LVM不是備份RAID也不是備份。它們只是提高可用性。真正的安全感來自定期、經過驗證的備份。我見過不少團隊因為迷信LVM快照和RAID10結果磁盤陣列卡故障時全盤數(shù)據(jù)一起完蛋連回滾的機會都沒有。所以建議你每個季度做一次備份恢復演練別把備份當成拷完就扔到角落里的文件。4. Systemd服務托管把服務的生死管起來4.1 Unit文件里的關鍵配置項拆解日常管理Linux服務總繞不開systemd。它取代了早期混亂的init腳本體系核心價值就一句話一個工具統(tǒng)一管理服務的啟動、停止、重啟、開機自啟和崩潰拉起。但很多初學者對它的理解停留在systemctl start xxx寫Unit文件時完全照抄模板出了詭異問題就干瞪眼。一個最小可用的Unit文件其實不難常見路徑是/etc/systemd/system/xxx.service。核心部分是[Unit]和[Service]這兩段。我在實際寫服務單元時最常用的配置大概是這樣的[Unit] DescriptionMY Web Application Service Afternetwork-online.target Wantsnetwork-online.target [Service] Typesimple Userappdeploy Groupappdeploy WorkingDirectory/opt/myapp ExecStart/usr/bin/python3 /opt/myapp/run.py Restarton-failure RestartSec5 EnvironmentCONFIG_PATH/etc/myapp/config.ini [Install] WantedBymulti-user.target這里幾個參數(shù)我逐個說清楚。Typesimple表示ExecStart啟動的進程就是主進程systemd不會另外做派生檢測。適用于絕大多數(shù)常駐進程。User和Group就是指定以哪個身份運行配合前面權限那塊內容服務絕不以root身份運行。Restarton-failure表示只有非正常退出時才重啟這是正確姿勢。如果寫成always手動停止服務后它也會被systemd再拉起來到時候你會以為服務出了靈異問題。RestartSec5是崩潰后等待5秒再拉起避免服務陷入頻繁崩潰重啟的死循環(huán)。寫完Unit文件后一定要重新加載systemctl daemon-reload systemctl enable --now myappenable是設置開機自啟--now意思是立即啟動兩個動作一步到位。4.2 怎么判斷服務是真的“活著”而不是“沒死透”用systemd管理服務你還會遇到一個問題進程在但已經卡死了算不算活著systemd默認只看進程是否存在而無法感知業(yè)務層面的心跳。這類問題最常見的場景是服務因為某個外部依賴比如數(shù)據(jù)庫連接池耗盡僵住進程不退出但業(yè)務已經完全中斷。我的經驗是給關鍵業(yè)務服務配置ExecStartPre來做啟動前檢查再配合自定義的健康檢查機制。舉個例子服務端可以暴露一個簡單的HTTP健康檢查接口而systemd本身沒有內置HTTP探測所以這個活通常是交給外部監(jiān)控來做。但在沒有外部監(jiān)控的情況下你可以利用Typenotify讓服務啟動完成后主動給systemd發(fā)一個“我準備好了”的信號服務內部再起一個線程定時探測業(yè)務健康度一旦異常就主動退出觸發(fā)systemd的Restarton-failure拉起邏輯。我看到不少剛入行的朋友在這塊容易想復雜其實核心就是systemd負責進程級別的守護業(yè)務級別的健康要靠應用程序自己上報狀態(tài)。兩邊配合好服務才算是真正被管住了。講到這里順帶提一句查看服務日志時不要再用一個個/var/log/messages翻。如果服務是systemd托管的直接journalctl -u myapp -n 200 --no-pager輸出里會帶上時間、進程號和標準化日志級別排查問題效率高得多。后面有一章我會專門展開日志排查技巧。5. 網絡與防火墻從排查到加固一氣呵成5.1 一套好用的網絡排查命令組合拳網絡問題在運維里是最容易讓人血壓升高的因為癥狀五花八門連不上、時通時不通、慢、丟包。我的排查思路是按鏈路從底層到高層走先確認物理層和鏈路層再確認IP層再確認傳輸層最后看應用層。對應的常用命令組合如下。第一步先看本機存活和IP配置ip addr show ip route show緊接著檢查有沒有丟包和錯誤ping -c 10 目標IP第二步通過ss查看本機的監(jiān)聽端口和服務連接狀態(tài)ss -tunap | head -50你會看到每個連接的本地地址、端口、遠端地址、狀態(tài)和所屬進程。排查“端口明明開著但外部連不上”的問題時這一步能快速看出來是不是服務只綁定在了127.0.0.1上。對這是個非常高頻的坑。很多程序默認只監(jiān)聽回環(huán)地址外部當然連不上。第三步查看ARP和鄰居表ip neigh show如果發(fā)現(xiàn)網關的MAC地址解析不出來那問題可能在二層網絡上。再往下走就是查連通性路徑traceroute -n 目標IP看看是到哪一跳之后斷了。而如果連接是通的但具體某個端口不通用nc或telnet做端口測試nc -vz 目標IP 端口這一套打下來大部分網絡問題都能定位到大概范圍。順序千萬別亂我見過有人一上來直接traceroute結果本機路由表就是錯的白白浪費半小時。5.2 firewalld管理規(guī)則的幾個要點防火墻配置是網絡安全的另一道閘門。以firewalld為例我的配置習慣是先確定這臺機器要對外提供哪些服務然后只開必要的端口或服務其余全部默認拒絕。一種常見的錯誤是把firewalld當成擺設在云廠商安全組和本機防火墻之間又開一層寬松放行等于層層設防層層裸奔。新增一個端口的放行規(guī)則可以這樣操作firewall-cmd --permanent --add-port8080/tcp firewall-cmd --reload注意--permanent不會立刻生效必須reload。如果只是臨時測試一下不加--permanent直接--add-port但重啟服務后規(guī)則會消失這也算一個新手容易迷糊的地方。我在生產機器上更傾向于使用富規(guī)則rich rule而不是單純放行端口。比如只允許某個來源IP訪問特定端口firewall-cmd --permanent --add-rich-rulerule familyipv4 source address192.168.1.100/32 port protocoltcp port9090 accept這樣做的好處是權限收得足夠窄。對外放行任何一個端口都意味著攻擊面擴大一分能限定來源就一定要限定。還有個小提醒修改防火墻規(guī)則后務必留一條后路給自己。我最擔心的運維事故之一就是遠程改防火墻把自己擋在外面。所以建議你在改任何防火墻規(guī)則之前先敲一條定時清理計劃任務比如10分鐘后自動reload之前的規(guī)則。如果確認改動沒問題再把這個計劃取消掉。這個土辦法救過我很多次。6. 日志分析與故障排查實錄6.1 journald日志的正確打開方式把systemd日志用好大概是排查效率提升最明顯的一步。以前看日志要跑到各個應用目錄去翻文件現(xiàn)在只需要統(tǒng)一在journald這一個入口查。但journald的日志量很大你得學會怎么精準地撈。常用的過濾維度有三個按服務、按時間、按優(yōu)先級。比如查看某個服務最近20分鐘內的錯誤級日志journalctl --since 20 minutes ago -p err -u myapp再比如查看某個時間段內所有日志方便慢定位一個跨系統(tǒng)的故障窗口journalctl --since 2025-01-15 10:00:00 --until 2025-01-15 10:30:00當journald日志本身占用的磁盤空間過大時可以通過journalctl --vacuum-time7d來清理超過7天的日志或者修改/etc/systemd/journald.conf里的SystemMaxUse參數(shù)限制最大體積。這個細節(jié)也容易引發(fā)磁盤寫滿的事故下面這個案例就是。6.2 一次“磁盤寫滿導致服務假死”的完整排查過程說一個典型的故障場景也是我用來帶新人練習的經典案例。某天業(yè)務方反饋某個核心服務響應極其緩慢甚至偶發(fā)超時。第一反應當然是去看監(jiān)控面板發(fā)現(xiàn)CPU和內存都還算健康但磁盤使用率到了99%。這個數(shù)字一出來心里基本就有數(shù)了大概率是磁盤寫滿導致日志寫入阻塞進而拖住了服務的主進程。接下來按順序做三件事。第一用df -h確認哪個分區(qū)滿了。第二用du -sh /var/log/*掃一遍日志目錄定位最占空間的文件。第三用journalctl --vacuum-time3d清理系統(tǒng)日志。如果應用日志很大直接考慮開啟logrotate讓日志按天滾動并壓縮。這里有個值得注意的點日志文件被進程打開著的情況下直接刪除文件并不會釋放磁盤空間。因為進程還持有該文件的句柄刪除只是摘掉了目錄項。正確的做法是用truncate -s 0 /var/log/xxx.log把日志文件清空讓進程繼續(xù)往里面寫等合適時機再配合logrotate做滾動。磁盤滿這個故障幾乎每個團隊都會遇到但每次踩的感受都一樣痛。它最好的治療方法不是出事之后去清理而是提前用logrotate把日志增長控制住。你需要做的是在/etc/logrotate.d/下寫一個配置舉個例子/var/log/myapp/*.log { daily rotate 7 compress delaycompress missingok notifempty copytruncate }關鍵參數(shù)說一下rotate 7保留7份compress壓縮舊日志copytruncate可以先復制再清空原文件避免服務進程句柄失效對不主動重開日志文件的程序非常友好。這套配置放上去服務日志在磁盤上不再無限膨脹你離“磁盤被日志塞滿”這個坑又遠了一步。7. Shell腳本加固與自動化巡檢7.1 巡檢腳本的思路和骨架手動巡檢的缺點是真有事情發(fā)生時你未必能及時發(fā)現(xiàn)。自動化巡檢腳本的價值就體現(xiàn)在這里。我的思路是寫一個小而精的巡檢腳本定時執(zhí)行把異常結果匯總發(fā)送到告警群或郵箱。腳本不需要很復雜貴在穩(wěn)定和精準。一個我常用的巡檢腳本骨架大概是這樣的檢查系統(tǒng)負載、檢查磁盤使用率、檢查關鍵端口存活、檢查內存余量、檢查最近是否有異常重啟記錄。每個檢查項盡量輸出清晰的狀態(tài)標識比如OK和FAIL方便一眼定位問題。如果你還是Shell腳本新手不用追求代碼看起來多高深保證正確性和可讀性更重要。我之前見過有人為了展示自己會寫復雜語法在巡檢腳本里搞了一堆花活兒結果部署后各種語法兼容問題。巡檢腳本是給系統(tǒng)穩(wěn)定服務的不是給你炫技的。7.2 讓Shell腳本在崩潰邊緣也能體面退出既然聊到Shell腳本多說幾句核心的健壯性設計。寫腳本時我第一行就會加上#!/usr/bin/env bash set -euo pipefail這四個選項分別解決不同的問題-e讓腳本在遇到未處理錯誤時立刻退出而不是帶著錯誤繼續(xù)執(zhí)行污染后續(xù)邏輯-u強制變量必須先定義再使用能攔截掉許多拼寫錯誤導致的詭異行為-o pipefail則保證管道中任何一個命令失敗都讓整個管道返回失敗狀態(tài)避免“前面失敗了但后面管道成功導致整體看起來成功”的假象。對沒有加set -euo pipefail習慣的朋友我給你一個場景你就能體會腳本里有一行cp a.txt /data/目錄不存在命令失敗了但腳本繼續(xù)往下跑最后把一個沒拷貝成功的文件當成成功結果傳給下一個流程最終產生一個詭異的數(shù)據(jù)錯誤。這個鍋最后到底算誰的恐怕要在日志里查半天才能翻出來。加上這些選項之后腳本會變得“脆弱”很多一有風吹草動就退出。這其實是好事因為退出得越早問題暴露得越早排查成本越低。但有的時候你確實希望允許某條命令失敗而不退出比如檢測某個可選文件是否存在那就用|| true或者顯式地處理錯誤邏輯把控制權拿回到自己手里。腳本里還有一個很實用的習慣永遠寫完整的路徑不要用相對路徑。比如rm -rf這種命令一旦腳本在錯誤的工作目錄下執(zhí)行相對路徑會把不該刪的東西刪掉。能嚴謹?shù)侥銓懙拿總€路徑都帶上/開頭腳本的生產級信任感才算到位。8. 自動化巡檢的定時任務配置8.1 crontab安排任務的具體做法巡檢腳本寫好了還得按時跑起來。crontab設計上非常簡單但就是有些常見的坑需要提前繞開。比如很少有人意識到cron任務執(zhí)行時的環(huán)境變量和你在終端里手動執(zhí)行腳本時并不完全相同。PATH會更短很多工具可能找不到。所以腳本里第一件事通常是顯式聲明路徑。我慣用的做法是給每個腳本加一個自定義環(huán)境變量文件或者干脆在腳本里把關鍵目錄全部用絕對路徑寫死。crontab的具體格式文檔到處都是我只強調幾個實際經驗。第一時間建議避開整點向0分和30分擠不然同一個時刻大量任務同時觸發(fā)IO和CPU會瞬時飆高。第二crontab任務輸出的日志一定要重定向到文件不然輸出會通過郵件發(fā)給root默認的mail服務還可能沒安裝日志直接丟失。一個推薦的crontab寫法是這樣的20 2 * * * /usr/bin/bash /opt/scripts/disk_check.sh /var/log/cron_disk.log 21這表示每天凌晨2點20分跑一次磁盤檢查標準錯誤也一并追加到同一個日志里。選了20分而不是0分就是錯開系統(tǒng)里其他常用的整點任務。8.2 巡檢發(fā)現(xiàn)異常后的響應機制腳本和定時任務只是自動化的一半另一半是觸發(fā)后的響應。很多團隊的巡檢腳本跑了好幾年異常日志堆成山卻沒人去看這等于白搞。所以我在設計巡檢系統(tǒng)時一定會留一個“出口”一旦檢測到異常指標立即發(fā)出告警。如果你暫時沒有成熟的監(jiān)控告警平臺可以先從一個最簡單的思路做起寫一個告警函數(shù)檢測到異常時調用系統(tǒng)里的mailx或者curl調用一個webhook把腳本輸出的異常信息發(fā)到群。這不需要引入任何重型組件只需一條命令的代價。最重要的還是保證告警不能誤報過于頻繁否則團隊會產生“告警疲勞”看見通知也麻木了。我通常會給指標設定合適的閾值和持續(xù)時間。比如磁盤使用率的閾值設置成85%持續(xù)異常兩次才告警一次這樣可以過濾掉瞬時波動帶來的騷擾。真正一次次踩過坑之后你會明白自動化不是為了替代人而是為了替人記得那些容易被遺忘的檢查項。一個系統(tǒng)管理員的成長往往就是從這些細節(jié)里堆出來的。前面從權限到存儲、從服務托管到日志排查、從腳本加固到定時巡檢點到為止地串了一遍。Linux的邊界很深但掌握這些實戰(zhàn)能力至少你已經有了一整套處理日常和突發(fā)問題的底氣。剩下的深度就在一臺臺真實的服務器里慢慢打磨吧。