简介:这是Linux压力测试工具stress的1.0.1源码压缩包,面向系统运维、开发及性能测试人员,用于模拟CPU、内存、磁盘I/O等高负载场景,快速评估系统稳定性与潜在瓶颈。压缩包共32个文件,体积仅199KB,除核心C源文件外,还包含configure配置脚本、Makefile构建文件,以及texi、html、info等格式的说明文档,目录结构规范,便于下载后直接编译安装并对照学习。目前已有3000余人浏览学习。对于需要开展系统压测或深入理解stress内部实现的读者,该源码包提供了完整的编译环境和配套文档,可结合README与示例脚本掌握CPU/内存压力参数配置,也能通过阅读源码了解工具的任务调度与资源消耗机制,为二次开发或定制压测方案打下基础。无论是服务器平台还是嵌入式环境,这套源码都有助于提前发现资源管理问题,提升系统可靠性。
1. 先弄清stress到底在压什么
刚装好的Linux服务器,跑起来看着一切正常,可一旦业务流量上来,CPU、内存、磁盘的隐患才会暴露。linux压力测试工具stress就是干这个的:它用一批worker进程生成可控的高负载,让机器在接近极限的状态下运行一段时间,提前暴露散热、供电、内核调度和资源上限的问题。适合刚入门的运维用来做装机验收,也适合开发者在发布前评估一台机器或一个容器的真实承载力。压力测试不是玄学,关键是先把工具选对、把参数设明白,再用系统自带命令验证压力是否真的到达了你想要的位置。
2. 装stress还是stress-ng:两个工具怎么选
2.1 原版stress的安装与最小验证
几乎所有主流发行版都内置了stress,包名就是stress。安装不需要纠结stress工具下载的渠道,直接用系统软件源就行。不同发行版命令略有区别,Debian/Ubuntu系用apt,CentOS/RHEL系用yum或dnf,Arch系用pacman。以下以Ubuntu和CentOS为例:
# Debian / Ubuntu sudo apt update sudo apt install -y stress # CentOS / RHEL / Rocky sudo yum install -y stress # 或者 sudo dnf install -y stress装完先确认版本,再跑一个最小压测来验证工具本身能正常工作。-c 2表示生成2个worker去执行CPU开方运算,-t 5表示5秒后自动退出,不会把机器长时间压住:
stress --version timeout 10 stress -c 2 -t 5如果你用的是国产Linux发行版,比如统信UOS、麒麟,软件源里通常也有stress,直接走系统自带的包管理器安装。5秒压测结束后,可以顺手用uptime看一眼load average,会看到1分钟负载有明显抬高。这个最小验证的目的只是确认命令可用,后续再按实际场景加大力度。
2.2 stress-ng能补上哪些长尾能力
原版stress的功能比较单一,只有-c(CPU)、-m(内存)、-i(IO)、-d(磁盘)四类worker,每个worker的行为也很固定。真实业务不会是单纯的死循环算开方,生产环境我更推荐用stress-ng,它是stress的加强版,worker类型多了一个量级,而且每个worker的负载比例可以按百分比调节。
# Debian / Ubuntu sudo apt install -y stress-ng # CentOS / RHEL / Rocky sudo yum install -y stress-ngstress-ng最实用的几个能力,是原版stress给不了的:
--cpu-load 50:让CPU worker只占单核50%的负载,原版stress只能压到100%,想模拟半载场景没门。--matrix 4:做矩阵乘法运算,这是数值计算场景更真实的负载模型。--sock 2:生成socket通信压力,适合测网络协议栈。--cache 2:压L2/L3缓存,原版stress完全没有缓存类压力。
两者的关系,我用一个对比表说明,方便你按需选型:
| 能力项 | stress | stress-ng |
|---|---|---|
| CPU开方运算worker | 有 | 有 |
| 内存分配worker | 有 | 有 |
| 磁盘写入worker | 有 | 有 |
| 负载百分比控制 | 无 | 有,--cpu-load |
| 矩阵运算/缓存/网络压力 | 无 | 有 |
| 随机性种子控制 | 无 | 有,--seed |
| 单worker内存上限 | 默认256MB | 可自由指定 |
| 输出日志 | 只有结束统计 | 可按秒输出 |
如果你只是想快速压一下CPU和内存,原版stress完全够用;如果你需要模拟更细粒度的业务负载,或者要给容器、云主机做资源极限测试,直接上stress-ng会少走弯路。两套命令参数风格几乎一致,从stress迁移到stress-ng的学习成本很低。
3. 压力参数的组合逻辑:CPU、内存、IO分别怎么压
3.1 压满CPU核数:-c与超线程
最常见的误用是把-c的数值直接写成CPU线程数。先查清楚机器到底有多少逻辑CPU,再决定worker数量:
nproc lscpu | grep -E "^CPU\(s\)|Thread|Core"nproc输出的是逻辑CPU数量,也就是操作系统看到的可用线程数。如果机器是8核16线程,nproc返回16,stress -c 16才能把所有逻辑核心跑满;只填8,负载就只有一半。压测的时候,要同时用mpstat确认每一核的压力分配,光看uptime里的load average是不够的:
mpstat -P ALL 1-P ALL表示打印每个CPU核心的独立使用率。如果看到部分核心在100%、部分核心在个位数,说明worker数量没对齐。还有一种情况是虚拟机宿主机超卖严重,你压16个worker,实际被调度到的物理核只有8个,这时mpstat会显示所有逻辑核都在忙,但单核频率上不去。遇到这种环境,不要慌,换个思路:压测的目的就是看这台虚拟机在调度竞争下的表现,记录实际吞吐数据就行。
3.2 压内存:--vm-bytes、--vm-hang与OOM边界
内存压测的意图不是把内存吃满就完事,而是让每个worker持续分配并touch内存页,触发真实的内存分配和换页路径。原版stress的-m参数生成内存worker,默认每个worker分配256MB,但实际场景往往需要指定总量:
stress -m 2 --vm-bytes 1G --vm-hang 60 -t 120这条命令生成2个内存worker,每个worker分配1GB内存并保持60秒不释放,整体内存占用量约2GB,压测持续120秒。--vm-hang的作用是让worker分配完内存后挂起一段时间,模拟“内存被占用但不释放”的状态。如果去掉--vm-hang,worker会不断分配、释放,测的是内存分配器的极限;加上它,测的是内存被持续占用时系统是否稳定。
设置--vm-bytes之前,先看物理内存和swap的现状:
free -h经验值是压测总量控制在物理内存的70%-80%。比如机器有8GB内存,可用量约7GB,压6GB以内是安全的。压到超过物理内存,系统开始用swap,压测时间一长就会触发OOM killer,这是另一种验证方式,但容易把SSH也波及,不适合在远程生产机上做。
3.3 磁盘IO的两种压法
原版stress的-i和-d经常被混为一谈,其实二者测的完全不是一回事。-i生成的是sync()系统调用压力,让内核不停刷脏页,测的是IO路径上的系统调用开销,CPU会被拖高,真实磁盘吞吐并不一定大幅上涨。-d才是真正写磁盘的worker,每个worker不断执行write和unlink,在临时目录里反复创建文件再删除:
stress -d 2 --hdd-bytes 512M -t 60--hdd-bytes控制每个磁盘worker一次性写入的字节量,这里设为512MB。这条命令会创建临时文件写满512MB再删掉,循环60秒,测试的是文件系统面对大量小文件创建删除时的表现。如果你想测大文件顺序写入,stress反而不合适,dd或fio更贴近真实业务。记住一个原则:stress的磁盘压力适合做“系统级稳定性验证”,不适合做“磁盘性能跑分”。跑分去用fio,压稳定性才用stress。
组合压测场景下,参数按需求叠加即可。比如同时压CPU和内存,让负载更接近真实的多线程服务:
stress -c 4 -m 2 --vm-bytes 2G -t 300参数之间用空格分隔,每个压力维度独立生效。下表是常用参数速查:
| 参数 | 作用 | 典型值 |
|---|---|---|
-c N | 生成N个CPU worker | 等于逻辑核数 |
-m N | 生成N个内存worker | 1-4 |
--vm-bytes | 每个内存worker分配的字节数 | 按物理内存70%分摊 |
--vm-hang | 分配后挂起秒数 | 60-300 |
-i N | 生成N个IO worker | 1-2 |
-d N | 生成N个磁盘worker | 1-2 |
--hdd-bytes | 每个磁盘worker写入的字节量 | 512M-2G |
-t N | 压测持续时间 | 300-3600 |
4. 从单条命令到持续压测:把stress接进测试流程
4.1 写一个可复用的压测脚本
单条命令适合临时验证,要做持续性压测,我一般会把参数、监控和数据收集写成一个bash脚本,这样既能复现结果,也能在压测结束后留一份完整的日志。脚本的逻辑分四段:读取参数、启动监控、运行stress、清理汇总:
#!/bin/bash # 压测脚本:压CPU和内存,采集负载数据 # 用法: ./stress_test.sh <CPU核数> <内存worker数> <时长> <日志前缀> CPU_NUM=${1:-4} MEM_WORKER=${2:-1} DURATION=${3:-300} LOG_PREFIX=${4:-stress_$(date +%Y%m%d_%H%M%S)} # 压测前的基线 uptime > ${LOG_PREFIX}_baseline.txt free -h >> ${LOG_PREFIX}_baseline.txt # 后台启动负载监控,压测结束后自动退出 (dstat -tcmn --output ${LOG_PREFIX}_dstat.csv > /dev/null 2>&1 & MON_PID=$! sleep ${DURATION} kill $MON_PID) & # 压测逻辑 stress -c ${CPU_NUM} -m ${MEM_WORKER} --vm-bytes 2G -t ${DURATION} # 压测结束后的采样 uptime >> ${LOG_PREFIX}_after.txt free -h >> ${LOG_PREFIX}_after.txt echo "压测完成,日志前缀: ${LOG_PREFIX}"脚本前半段用dstat在后台按秒采集CPU、内存、网络和IO数据,写入CSV文件;-tcmn分别表示task、cpu、memory、network四类指标。后半段stress运行时长与监控时长一致,stress退出后kill监控进程。注意dstat可能没装,Debian系先apt install dstat,CentOS系是yum install dstat。
这个脚本的好处是把“压测”和“观察”做成一个闭环:stress负责制造压力,dstat负责记录压力下的系统表现。上次我在一台8核16线程的机器上跑300秒,最后翻出CSV一看,发现某个核在压测中段温度触顶降频,频率曲线掉了一截——用一条裸的stress命令根本发现不了这种问题。
4.2 结合top、mpstat、dstat观察负载是否达标
压测跑起来之后,需要确认压力真的落在了你希望的位置。第一步看uptime的load average,数值至少要超过逻辑核数的一半,比如16线程的机器load到8以上,才算明显施压。第二步看top的进程列表,stress的worker进程应该占据前几行,且CPU时间持续累加:
top -b -n 1 | head -20-b是批处理模式,-n 1只取一次快照。观察%CPU列,理想状态是每个worker都接近100%。如果worker的CPU占比参差不齐,比如有的98%、有的45%,说明调度器在做均衡,或者某些核心被其他进程抢占。此时配合mpstat -P ALL 1看单核视图,能定位到是哪几个核没有吃满。
dstat的实时输出更直观:按dstat -tcmn 2,每两秒刷新一行,从左到右依次是时间、task、cpu、memory、network。压测中的CPU us列应该接近100%,free列的内存余量应逐步下降并稳定在低水位。如果dstat里出现大量swap列数值,说明内存压测超限了,需要按3.2节的边界重新评估--vm-bytes。
压测结束的判定,不是stress自动退出就万事大吉。恢复常态后,uptime的load要在几分钟内回落,free -h里被占用的内存要被释放。如果load始终不降,或者内存一直处于high water mark状态,说明系统可能存在内存泄漏或内核调度异常,这才是压测真正要暴露的问题。
5. 避坑:5条最常见的stress翻车现场
5.1 CPU压不到100%,只看到负载曲线忽高忽低
现象:stress -c 16跑在16线程的机器上,top看到每个worker的CPU占比只有50%-80%,整体负载波动明显。
原因:最常见是超线程的影响。逻辑核共享物理核的运算单元,16个逻辑核全部满载时,物理核的资源竞争会让每个逻辑核都拿不到满血频率。此外,电源管理策略和云主机的CPU限流也会造成同样表现。
解决:先用lscpu确认物理核数和逻辑核数。如果是云主机,看当前规格是否限制了单核频率,常见做法是用stress-ng --cpu 16 --cpu-method all --cpu-load 100交叉验证。如果所有方法都压不满,这台机器本身就存在CPU资源上限,记录实际能压到的峰值即可,不必要追求数字上的100%。
5.2 内存压测把系统搞到冻结,SSH直接断开
现象:stress -m 4 --vm-bytes 4G跑在两台低配机器上,内存总量才8GB,压测开始不到1分钟整个系统卡死,远程连接全部超时。
原因:--vm-bytes 4G乘以4个worker是16GB,远超8GB物理内存,系统疯狂做swap换页,CPU全耗在页迁移上,连SSH的keepalive包都得不到响应。
解决:压测前用free -h计算实际可用内存,总压力量控制在物理内存70%以内,8GB机器压5G左右。另外设置--vm-hang不要超过300秒,避免长时间占压导致缓存被挤干净。这里有一条血泪经验:远程服务器压内存,建议加上-t 60的护栏,短时验证通过后再逐步延长。
5.3 用-d测磁盘IO,跑分数据跟业务完全对不上
现象:stress -d 2 --hdd-bytes 1G跑出来的磁盘“吞吐”很高,但接到真实业务场景后,同样的存储设备表现天差地别。
原因:stress的-dworker是write和unlink的高速循环,测的是文件系统创建删除小文件的元数据操作能力,不是大文件持续读写的块设备性能。业务里如果是数据库随机读写或者日志连续追加,stress完全模拟不了。
解决:认清定位。压系统稳定性用stress没问题,验证磁盘性能就换工具。顺序读写用dd,随机读写和延迟分布用fio,两者组合才是一套完整的磁盘验证方案。
5.4 stress进程跑着跑着被杀了,压测中断
现象:压测进行到一半,top里stress进程消失,dmesg里有大量Out of memory和oom-killer日志。
原因:内存压力超过阈值后,内核OOM killer介入,挑“占用内存大且存活价值低”的进程杀掉。stress的内存worker优先级不高,是典型的被杀对象。
解决:如果是正经压测,用--vm-bytes控制总量在安全范围内,别让OOM killer参战。如果你恰好就是要验证OOM场景,那就明确这一点,把-m --vm-bytes设置到内存的120%,并准备好物理控制台。生产机上不要玩这种心跳操作,OOM killer有可能把业务进程也顺手带走。
5.5 容器里跑stress,压出来的数据不能平移到宿主机
现象:在容器里用stress -c 8压测,容器内看CPU 100%,但宿主机上实际负载只到一半,反向情况也可能出现。
原因:容器看到的是cgroup和namespace隔离后的视图,CPU压力被限制在容器分配的quota内。反过来,容器共享宿主机内核,压测产生的系统调用会波及同宿主机的其他容器。
解决:压容器必须明确边界。先看docker inspect或kubectl describe确认CPU limit,stress的worker数不能超过limit值。压测时用docker stats观察容器维度的CPU和内存,同时登录宿主用top观察全局影响。容器压测的结论只对容器生效,不要拿它推导宿主机整体承载能力,两者根本不在一个隔离层级上。
6. 用stress验证一台新服务器:按脚本跑的完整过程
新服务器上架验收,我习惯按一个固定流程跑stress:先看基线,再压CPU,压内存,最后压组合场景。以一台4核8线程、16GB内存的机器为例,完整命令如下:
# 第一步:记录基线 uptime && free -h && cat /proc/cpuinfo | grep "model name" | head -1 # 第二步:压CPU 5分钟 stress -c 8 -t 300 # 观察top,确认每个worker接近100% # 第三步:压内存 5分钟,总压力量控制在物理内存70% stress -m 4 --vm-bytes 3G --vm-hang 120 -t 300 # 第四步:CPU+内存组合压测10分钟 stress -c 8 -m 4 --vm-bytes 2G -t 600 # 第五步:压测结束,查看回落情况 sleep 30 && uptime && free -h第五步是大多数新手最容易漏掉的。stress退出后,系统需要时间回收内存、清空负载队列,如果30秒后load还停留在高峰不下来,就要怀疑机器是否存在资源泄漏或调度异常。我自己的习惯是压完再看一眼mpstat -P ALL 3输出,确认所有逻辑核的使用率都回落到个位数,才算这台机器真正通过了验收。
这套流程跑完,你能得到三个明确结论:这台机器的CPU在持续满载下稳不稳、内存分配和释放是否有异常、组合负载下系统会不会出现资源争抢导致的卡顿。对于装了新内核、换了散热器、迁移到新云主机规格的场景,它比任何跑分软件都更能说明问题。一次压测暴露温度降频后,我后来每台机器验收都会加跑10分钟全核满载,这个习惯帮我提前拦下了不少“看着正常、一上线就翻车”的隐患。希望帮到你。
本文还有配套的精品资源,点击获取