:從安裝到拷機(jī)一條龍)
簡介Linux壓力測試工具stress 1.0.1源碼資源包面向系統(tǒng)管理員、運維工程師與嵌入式開發(fā)者用于模擬CPU、內(nèi)存、線程/進(jìn)程等負(fù)載評估系統(tǒng)在極限場景下的穩(wěn)定性與性能表現(xiàn)。壓縮包整體約199KB共32個文件以C源碼、configure配置腳本、Makefile構(gòu)建文件為主兼有texinfo文檔、man手冊及ChangeLog等說明材料目錄沿用標(biāo)準(zhǔn)GNU工程結(jié)構(gòu)便于編譯、安裝與二次開發(fā)。該工具支持通過命令行靈活指定負(fù)載類型與線程數(shù)量可模擬計算密集、內(nèi)存緊張及高并發(fā)進(jìn)程創(chuàng)建等場景。目前已有3031人學(xué)習(xí)下載適合需要驗證服務(wù)器承載力、排查資源瓶頸或開展性能調(diào)優(yōu)的工程師。借助該包可收獲完整源碼與配套文檔既能直接用于壓測環(huán)境搭建也能深入研讀stress的核心實現(xiàn)為自行編寫輕量級負(fù)載工具提供參考。linux壓力測試工具stress實戰(zhàn)從裝庫到拷機(jī)一條龍做Linux運維和系統(tǒng)性能驗證的朋友一定繞不開一個場景新買的服務(wù)器到了要驗證硬件穩(wěn)不穩(wěn)內(nèi)核打了一個補丁要確認(rèn)系統(tǒng)不會跑著跑著就崩部署容器之前要看看資源隔離到底靠不靠譜。這些場景都有一個共同的底子需求——給系統(tǒng)施加一個可控的壓力然后在壓力下觀察它的表現(xiàn)。stress就是干這個的一個輕量、純粹、用來給Linux系統(tǒng)制造負(fù)載的小工具我用它做過不少次拷機(jī)和穩(wěn)定性驗證這篇就來聊聊它的完整玩法。1. 工具選型與核心概念1.1 stress到底是個什么工具stress是Amos Waterland寫的一個C語言小工具它的設(shè)計目標(biāo)非常純粹通過fork出大量子進(jìn)程分別去消耗CPU、內(nèi)存、磁盤I/O和資源分配能力從而讓系統(tǒng)進(jìn)入一種可量化、可控的高負(fù)載狀態(tài)。說人話就是——你告訴它“給我壓出8個滿負(fù)荷CPU的負(fù)載”它就老老實實fork出8個進(jìn)程每個進(jìn)程拼命算數(shù)學(xué)題把CPU時間吃滿。很多人會把stress和stress-ng搞混。stress-ng是它的加強(qiáng)版包含幾百種壓測方法功能更強(qiáng)但復(fù)雜度也高。而stress的特點是參數(shù)簡單、行為直觀、結(jié)果容易判斷適合做快速驗證和日常拷機(jī)。我個人的習(xí)慣是快速驗證用stress深度專項壓測用stress-ng或sysbench但日常工作中stress出現(xiàn)的頻率其實更高因為它足夠輕量裝完即用不引入太多學(xué)習(xí)成本。1.2 為什么需要給系統(tǒng)制造壓力很多人會有疑問我的服務(wù)已經(jīng)在線上跑了為什么還要額外制造壓力這里有個概念要分清線上跑業(yè)務(wù)是“實際負(fù)載”壓測工具制造的是“人工負(fù)載”。實際負(fù)載是隨機(jī)的、起伏的、不好控制的而人工負(fù)載是確定的、穩(wěn)定的、可調(diào)節(jié)的。做穩(wěn)定性驗證時你不希望負(fù)載忽高忽低導(dǎo)致結(jié)果無法解釋你希望CPU穩(wěn)定在100%、內(nèi)存穩(wěn)定占用N個GB然后觀察系統(tǒng)在這種極端情況下是否還能正常工作。stress的價值就在這里它把負(fù)載變成了一個有刻度的儀器讓你能夠在“系統(tǒng)扛不住之前”就掌握系統(tǒng)的邊界在哪里。比如一臺8核機(jī)器先壓6個CPU看看是否穩(wěn)定再壓8個再壓10個超賣觀察不同負(fù)載級別下的系統(tǒng)行為。這種測試在硬件驗收、性能基線采集、容器限制驗證中都屬于必備環(huán)節(jié)。1.3 適用場景梳理從我實際接觸過的使用場景來看stress主要適合以下幾種情況硬件拷機(jī)新裝機(jī)或購買二手服務(wù)器后用CPU和內(nèi)存壓力驗證硬件是否有隱性故障。內(nèi)核與驅(qū)動驗證打了補丁、升級了內(nèi)核、更換了驅(qū)動需要在負(fù)載下確認(rèn)系統(tǒng)不會panic或死鎖。性能調(diào)優(yōu)前后對比調(diào)整內(nèi)核參數(shù)、CPU調(diào)頻策略之前和之后用同樣的壓力對比系統(tǒng)表現(xiàn)。容器與虛擬化資源限制驗證確認(rèn)cgroup的CPU限制、內(nèi)存限制是否真正生效。教學(xué)和技術(shù)測試演示系統(tǒng)負(fù)載、觀察調(diào)度行為時stress是干凈利落的負(fù)載制造工具。2. 安裝部署與環(huán)境準(zhǔn)備2.1 各主流發(fā)行版的安裝方法stress的安裝非常簡單官方源里基本都有現(xiàn)成的包。以最常見的幾個發(fā)行版為例# Debian / Ubuntu sudo apt-get install stress # CentOS / RHEL 7/8/9 sudo yum install stress # Fedora sudo dnf install stress # Arch Linux sudo pacman -S stress如果你用的是極其精簡的發(fā)行版或者沒有現(xiàn)成包也可以從源碼編譯安裝。stress的源碼包很小編譯過程依賴也很少wget https://downloads.your.org/stress/stress-1.0.7.tar.gz tar -xzf stress-1.0.7.tar.gz cd stress-1.0.7 ./configure make sudo make install安裝完成之后驗證一下是否成功stress --version能輸出版本號就說明OK了。我在編譯安裝時踩過一次坑某些精簡系統(tǒng)上缺少make和gcc需要先用包管理器裝好基礎(chǔ)編譯工具鏈再執(zhí)行configure。2.2 壓測前的系統(tǒng)狀態(tài)確認(rèn)在做壓力測試之前有一件小事經(jīng)常被忽略確認(rèn)CPU調(diào)頻策略?,F(xiàn)在的CPU大多有自動調(diào)頻功能空閑時降頻省電負(fù)載高時自動升頻。如果你不做任何設(shè)置壓測過程中CPU頻率可能忽高忽低測試結(jié)果的一致性會受影響。建議在壓測前把CPU調(diào)到最大頻率或性能模式觀察一下當(dāng)前頻率運行狀態(tài)# 查看當(dāng)前CPU頻率 cat /proc/cpuinfo | grep MHz # 使用cpupower工具設(shè)置性能模式需要root權(quán)限 cpupower frequency-set -g performance如果發(fā)行版沒有cpupower命令也可以裝linux-cpupowerDebian/Ubuntu或kernel-toolsCentOS包。當(dāng)然如果你測試的目的恰恰是要驗證調(diào)頻策略本身的行為那就不需要這一步反而應(yīng)該保持默認(rèn)策略去壓具體取決于你的目標(biāo)。另外壓測前還要確認(rèn)系統(tǒng)負(fù)載基線是干凈的。最好在一臺沒有業(yè)務(wù)的機(jī)器上做壓測或者至少確認(rèn)當(dāng)前top顯示的load average不高避免把別人業(yè)務(wù)的負(fù)載誤算進(jìn)你的測試結(jié)果里。3. 壓測方案設(shè)計與核心參數(shù)3.1 CPU壓測--cpu參數(shù)詳解stress最常見的用法是CPU壓測命令格式如下stress --cpu 8這會在當(dāng)前終端前臺fork出8個子進(jìn)程每個進(jìn)程執(zhí)行一個計算平方根的死循環(huán)把CPU核心吃滿。根據(jù)我的實測每個--cpu進(jìn)程會跑在單核上8個進(jìn)程就能吃滿8個邏輯核心。機(jī)器有多少核心可以用nproc查看。這里有個決策點如果機(jī)器是超線程架構(gòu)8核16線程要壓滿所有邏輯核心應(yīng)該用--cpu 16還是只壓8個物理核心這取決于你的目的。如果你想驗證整機(jī)散熱和供電是否扛得住那就壓滿16個線程讓所有邏輯處理器都進(jìn)入高負(fù)載狀態(tài)如果你想模擬“每個物理核心承載一個典型業(yè)務(wù)進(jìn)程”的場景壓8個可能更貼近實際。CPU壓測默認(rèn)會一直跑下去直到你按CtrlC終止。實際操作中通常需要限制時長用--timeout參數(shù)# 壓8個CPU核心持續(xù)60秒后自動退出 stress --cpu 8 --timeout 60s--timeout支持10s、1m、1h、1d這樣的時間后綴也支持純數(shù)字單位為秒。加上超時控制的最大好處是不用干等測試完自動退出適合寫進(jìn)腳本里循環(huán)執(zhí)行。3.2 內(nèi)存壓測--vm參數(shù)詳解內(nèi)存壓測用到--vm系列的參數(shù)# 啟動4個內(nèi)存壓測進(jìn)程每個分配512MB內(nèi)存 stress --vm 4 --vm-bytes 512M每個--vm進(jìn)程會調(diào)用malloc分配指定大小的內(nèi)存然后循環(huán)寫入數(shù)據(jù)確保內(nèi)存頁真實被觸達(dá)。這里我補充一個容易被忽視的細(xì)節(jié)malloc分配出來的內(nèi)存在沒有寫入之前只是虛擬內(nèi)存不會占據(jù)實際的物理內(nèi)存頁。stress內(nèi)部會通過寫入操作對這些內(nèi)存頁進(jìn)行實際觸達(dá)這也是它壓內(nèi)存比較有效的原因。實際壓測時內(nèi)存總量要算清楚。比如機(jī)器有8GB可用內(nèi)存你啟動4個進(jìn)程每個分配2GB總量就是8GB。如果分配總量超過實際可用內(nèi)存系統(tǒng)會開始使用swap性能會驟降如果超過物理內(nèi)存加swap的總量則可能觸發(fā)OOM Killer某個進(jìn)程被內(nèi)核殺掉測出來的結(jié)果就不具備參考意義。還有--vm-hang參數(shù)值得說明。它會指示子進(jìn)程在分配并寫入內(nèi)存后掛起一段時間而不是反復(fù)隨機(jī)讀寫。比如stress --vm 2 --vm-bytes 1G --vm-hang 30兩個進(jìn)程各分配1GB內(nèi)存并保持30秒不釋放。這種模式適合測試“系統(tǒng)在內(nèi)存長期以高占用率運行時是否穩(wěn)定”貼近數(shù)據(jù)庫緩存、JVM堆內(nèi)存這類常駐內(nèi)存場景。3.3 磁盤和I/O壓測--io與--hdd磁盤I/O壓測主要有兩個參數(shù)--io和--hdd。# 啟動4個I/O進(jìn)程每個進(jìn)程不斷執(zhí)行sync系統(tǒng)調(diào)用 stress --io 4--io的做法是不斷fork新進(jìn)程執(zhí)行sync()把文件系統(tǒng)緩沖區(qū)刷入磁盤產(chǎn)生系統(tǒng)調(diào)用和I/O調(diào)度壓力。不過說實話這種壓測方式對現(xiàn)代SSD來說壓力并不大它更多是壓內(nèi)核的I/O路徑和調(diào)度器不是直接壓磁盤帶寬。想要更直接的磁盤寫入壓力用--hdd# 啟動2個寫盤進(jìn)程每個向文件中寫入1GB數(shù)據(jù) stress --hdd 2 --hdd-bytes 1G--hdd進(jìn)程會創(chuàng)建一個臨時文件默認(rèn)在/var/tmp目錄下然后反復(fù)寫數(shù)據(jù)進(jìn)去。這個測試會真實產(chǎn)生磁盤寫入流量可以用來驗證磁盤的穩(wěn)定性和散熱。這里有一個我踩過的坑--hdd默認(rèn)會在/var/tmp下生成臨時文件對于容量小的根分區(qū)1GB甚至幾GB的寫入很容易把根分區(qū)磁盤占滿。所以在跑--hdd之前一定先看看磁盤剩余空間同時建議用--hdd-bytes限制單次寫入上限或者指定文件路徑。3.4 組合壓測模擬真實混合負(fù)載前面的參數(shù)都是單一維度的但生產(chǎn)環(huán)境的負(fù)載從來不會只消耗一種資源。stress允許同時指定多個維度一次壓測模擬混合負(fù)載# 8個CPU進(jìn)程 2個內(nèi)存進(jìn)程各1G 1個磁盤寫入進(jìn)程持續(xù)5分鐘 stress --cpu 8 --vm 2 --vm-bytes 1G --hdd 1 --hdd-bytes 1G --timeout 5m這種組合壓測更適合在真實服務(wù)器上做整體穩(wěn)定性驗證。比如你新部署了一個生產(chǎn)環(huán)境想確認(rèn)在“CPU高負(fù)載、內(nèi)存大量占用、磁盤持續(xù)寫入”的場景下業(yè)務(wù)進(jìn)程還能不能穩(wěn)定響應(yīng)這種混合壓測就很有參考價值。我在實際做服務(wù)器驗收時幾乎都是用組合參數(shù)跑30分鐘以上而不僅僅是單測一個維度。3.5 核心參數(shù)速查表參數(shù)作用常用搭配備注--cpu N啟動N個CPU負(fù)載進(jìn)程--timeout每個進(jìn)程吃滿一個邏輯核心--vm N啟動N個內(nèi)存負(fù)載進(jìn)程--vm-bytes每個進(jìn)程分配指定大小內(nèi)存--vm-bytes SIZE指定每個內(nèi)存進(jìn)程分配的大小--vm N支持K/M/G后綴--vm-hang N內(nèi)存分配后掛起N秒--vm模擬常駐內(nèi)存負(fù)載--io N啟動N個I/O進(jìn)程--timeout不斷執(zhí)行sync系統(tǒng)調(diào)用--hdd N啟動N個寫盤進(jìn)程--hdd-bytes真實產(chǎn)生磁盤寫入流量--timeout TIME指定總運行時長所有參數(shù)支持s/m/h/d后綴--verbose顯示詳細(xì)壓測日志任意配合調(diào)試使用4. 實操過程與數(shù)據(jù)觀察4.1 一個完整的壓測流程示例在真正壓測之前我先做一次基線采集也就是不做任何壓測時記錄系統(tǒng)初始狀態(tài)。這一步很重要因為后續(xù)判斷異常都需要和基線對比uptime free -h df -hT /var/tmp mpstat -P ALL 1 3假設(shè)我現(xiàn)在拿到一臺8核16G的服務(wù)器要做一次硬件穩(wěn)定性驗收壓測方案分三步走第一步跑CPU壓力10分鐘確認(rèn)所有邏輯核心都穩(wěn)定在100%負(fù)載stress --cpu 16 --timeout 10m第二步跑內(nèi)存壓力按70%內(nèi)存占用設(shè)計16G機(jī)器留出系統(tǒng)余量分配12G占用stress --vm 6 --vm-bytes 2G --timeout 10m第三步混合壓測30分鐘模擬真實業(yè)務(wù)的高負(fù)載場景stress --cpu 16 --vm 4 --vm-bytes 2G --hdd 4 --hdd-bytes 2G --timeout 30m三個步驟跑完如果沒有出現(xiàn)進(jìn)程被kill、系統(tǒng)死機(jī)、內(nèi)核報錯等現(xiàn)象基本可以認(rèn)為這臺機(jī)器的硬件和系統(tǒng)在合理的負(fù)載范圍內(nèi)是穩(wěn)定的。4.2 壓測過程中的數(shù)據(jù)觀察方法壓測啟動后記住一個原則不要只盯著黑色終端等結(jié)果要開另一個終端去觀察系統(tǒng)狀態(tài)。我最常用的觀察工具組合如下top/htop看整體CPU使用率、load average、內(nèi)存占用判斷壓測進(jìn)程是否達(dá)到預(yù)期負(fù)載。mpstat -P ALL 1逐核查看CPU使用率。這個非常關(guān)鍵能看出壓力是否均勻分布在所有核心上如果只有部分核心為100%說明壓測進(jìn)程數(shù)量少了或者存在中斷綁核等問題。free -h查看內(nèi)存與swap使用情況。如果內(nèi)存壓測導(dǎo)致swap開始大量增長說明壓測內(nèi)存分配過量不是理想狀態(tài)。iostat -x 1觀察磁盤使用率、吞吐量和I/O等待時間配合--hdd壓測使用。這里我舉個例子。用stress --cpu 8壓一臺8核機(jī)器在另一個終端跑mpstat -P ALL 1正常情況下每個CPU的%usr都接近100%。但如果發(fā)現(xiàn)其中某個CPU的%usr只有50%左右可能就是stress進(jìn)程被調(diào)度到了中斷處理較多的CPU上或者系統(tǒng)本身有綁核配置。這種細(xì)節(jié)在高精度壓測中值得排查。4.3 壓測時的安全注意事項壓測說到底是在挑戰(zhàn)系統(tǒng)的極限所以要講究分寸。幾個我吃過虧的教訓(xùn)分享給你第一不要在遠(yuǎn)程連接的唯一會話里直接跑大壓力測試。如果你用的是SSH連服務(wù)器跑壓力測試壓力過大可能導(dǎo)致系統(tǒng)響應(yīng)變慢甚至假死你的SSH連接有可能斷掉然后你就失去了對機(jī)器的控制。建議用tmux或screen起一個會話跑壓測即使連接斷了壓測進(jìn)程還能繼續(xù)運行重新連上后還能看到之前的輸出。第二內(nèi)存壓測總量一定要留余量。別把物理內(nèi)存壓到100%給系統(tǒng)內(nèi)核和基礎(chǔ)服務(wù)留出幾百MB甚至更多的余量否則OOM Killer啟動后可能把不該殺的系統(tǒng)服務(wù)給殺了測試結(jié)果會被嚴(yán)重污染。第三跑磁盤壓測前確認(rèn)磁盤空間和磨損程度。如果是機(jī)械硬盤或老舊SSD的機(jī)器長時間--hdd壓測會加劇磁盤磨損。這種測試不是不能做但要有目的性不是為了測磁盤本身就沒必要長時間跑。5. 常見問題與排查技巧實錄5.1 壓測以后系統(tǒng)負(fù)載降不下來這個問題我遇到不只一次。明明按了CtrlC或者--timeout到了時間系統(tǒng)負(fù)載依然很高。排查步驟是這樣的先用top看是哪個進(jìn)程在消耗CPU如果是stress的殘留子進(jìn)程用pkill -f stress清理。注意stress的父進(jìn)程退出后某些子進(jìn)程可能會變成孤兒進(jìn)程繼續(xù)運行。這時可以pgrep -l stress列出所有名字包含stress的進(jìn)程逐個確認(rèn)后清理pkill -9 stress另外如果CPU壓測跑完LOAD值依然很高但CPU使用率已經(jīng)降下來了那可能是系統(tǒng)在刷臟頁或等待I/O完成這時候耐心等一下就好通常不會持續(xù)太久。5.2 內(nèi)存壓測觸發(fā)OOM Killer內(nèi)存壓測時系統(tǒng)報錯Out of memory: Kill process說明壓測配置和機(jī)器實際內(nèi)存不匹配。比如一臺只有4G內(nèi)存的機(jī)器你直接跑stress --vm 8 --vm-bytes 1G8個進(jìn)程共需要8G內(nèi)存遠(yuǎn)超物理內(nèi)存OOM Killer就會出手。解決方案是精確計算內(nèi)存分配量。建議先看free -h確定可用內(nèi)存最多用70%到80%的可用內(nèi)存做壓測。假設(shè)機(jī)器有8G內(nèi)存系統(tǒng)已用2G可用約6G那壓測內(nèi)存量控制在4G到5G比較合適可以配置成stress --vm 4 --vm-bytes 1G還有一種情況你確實想壓到OOM看系統(tǒng)能不能正確殺掉內(nèi)存超限進(jìn)程從而保護(hù)主機(jī)不掛這種測試在容器環(huán)境驗證時其實是有效的驗證手段。但如果你的目標(biāo)是驗證“系統(tǒng)在內(nèi)存高負(fù)載下穩(wěn)定運行”那就要避開OOM閾值。5.3 --hdd壓測后臨時文件沒清理干凈stress --hdd跑完后會在/var/tmp下留下臨時文件按我的經(jīng)驗它會以類似stress.XXXXXX的命名方式寫入文件。如果不清理日積月累會占用不少磁盤空間。清理命令很簡單ls /var/tmp/ rm -f /var/tmp/stress.*為了避免這個問題更推薦的做法是在命令里就指定臨時文件路徑放到專門的測試目錄下測完直接刪目錄mkdir /tmp/stress-test stress --hdd 2 --hdd-bytes 1G --timeout 1m跑完以后刪除整個測試目錄干凈利落。5.4 壓測過程中SSH超時斷連這是一個很實際的運維場景你通過SSH連接服務(wù)器跑長時間壓測壓測到一半SSH連接斷了。排查思路是先確認(rèn)是不是網(wǎng)絡(luò)側(cè)的會話超時限制同時建議所有長時間壓測都放進(jìn)tmux會話中執(zhí)行。我已經(jīng)養(yǎng)成習(xí)慣凡是超過10分鐘的壓測一律先建tmux會話tmux new -s stress-test stress --cpu 16 --timeout 1h # 按 CtrlB 再按 D 脫離會話連接斷了也不影響壓測進(jìn)程重新連接后用tmux attach -t stress-test回到壓測會話查看輸出情況。這個習(xí)慣幫我避免了多次遠(yuǎn)程壓測斷連后無法確認(rèn)結(jié)果的麻煩。5.5 壓測結(jié)果如何判斷是否成功最后聊一下怎么判斷壓測結(jié)果。stress本身不會輸出一個“通過/失敗”的結(jié)論你需要自己綜合判斷。我個人的判斷標(biāo)準(zhǔn)有三條壓測期間系統(tǒng)沒有出現(xiàn)嚴(yán)重錯誤日志dmesg中沒有OOM、panic、硬件報錯。壓測結(jié)束后SSH和基礎(chǔ)服務(wù)依然正常響應(yīng)負(fù)載能回落到正常水平。壓測期間業(yè)務(wù)進(jìn)程如果有沒有出現(xiàn)崩潰或者長時間無響應(yīng)。這三條都滿足這臺機(jī)器基本可以認(rèn)定在當(dāng)前壓測配置下是穩(wěn)定的。如果再嚴(yán)格一點可以對比壓測前后/proc/cpuinfo和smartctl的磁盤健康狀態(tài)確認(rèn)沒有新增的硬件隱性故障。結(jié)尾我在實際使用stress過程中最大的體會是工具本身簡單到不行真正的復(fù)雜度在于你怎么設(shè)計壓測方案和解讀壓測結(jié)果。壓測之前先想清楚要驗證什么再動手跑數(shù)據(jù)才有參考價值。最后分享一個小技巧如果你需要定期做壓力測試可以寫一個腳本把stress和stress-ng配合使用先用stress做快速冒煙驗證確認(rèn)基本功能正常后再用stress-ng做專項深度壓測這樣兼顧了效率與深度我在多個項目的服務(wù)器驗收中都是這么做的效果一直不錯。本文還有配套的精品資源點擊獲取