简介:这是Linux平台上一款经典的压力测试工具stress的完整源码与文档包,面向系统管理员、运维工程师和性能测试开发者,可通过模拟CPU、内存的高负载场景,检验服务器在多任务并发下的稳定性、散热表现与极限吞吐能力,可用于服务器选型、超频验证、云主机压测等场景。资源包共收录32个文件,压缩后约199KB,核心为stress-1.0.1源码(stress.c),配套configure配置脚本、Makefile.am/in构建文件、Texinfo格式权威文档(stress.texi)及README、ChangeLog、INSTALL等说明材料,既适合阅读源码理解压力测试实现原理,也便于在本地直接编译安装。学习后可掌握stress如何用多线程执行无意义计算耗尽CPU、如何分配并持续读写内存以测试内存带宽与虚拟内存管理,同时理解--cpu、--vm、--vm-bytes等参数组合的实际效果,还可结合top、htop、vmstat、iostat等工具进行实时观测,形成一套完整的系统压测与结果分析方法。已有1036人学习该资源,尤其适合希望深入Linux底层性能机制并动手实践的中高级用户。
1. 为什么用 stress 给 Linux 加压:先搞懂它测的是什么
当服务器在业务高峰时频繁卡顿,或者刚上线的机器跑几天就重启,第一反应往往是“去看监控”。但监控只能告诉你系统现在不行,没法告诉你硬件和内核到底能扛多大压力。stress linux加压测试工具的价值,就是让你在改配置、换硬件、调内核参数之前,先把机器按需求压到极限,用可控的方式暴露问题。它不是跑分工具,不输出性能分数,它的职责是制造高负载场景,配合运维常用的监控命令,判断这台 Linux 是否稳定。这篇文章适合刚接触系统压力测试的运维新手,也适合想把手里的服务器压出真实能力的嵌入式 Linux 开发者。
2. 安装与最小复现:从 apt/yum 到跑通第一个 CPU 压力测试
2.1 在 Debian/Ubuntu 和 CentOS/RHEL 上安装 stress
stress 在主流 Linux 发行版仓库里都有,属于“镜像安装完就能用”的轻量工具。Debian/Ubuntu 用 apt,CentOS/RHEL 用 yum;国产 Linux 里大多数也兼容这两类包管理。下面是两条常见安装命令:
# Debian / Ubuntu / Mint sudo apt update && sudo apt install -y stress # CentOS / RHEL / Rocky Linux / Alinux sudo yum install -y stress安装完用stress --version或which stress检查。这里最容易踩的坑是:CentOS 最小化安装后没有启用 EPEL 源,直接yum install stress会提示No package stress available。常见的做法是先安装 EPEL:
sudo yum install -y epel-release sudo yum install -y stress为什么优先用发行版自带包?因为 stress 依赖很少,自带包足够跑完所有参数,没必要自己编译。如果你恰好在一台没有外网源的离线机器上,常见做法是找一台同架构机器把stress的 rpm 或 deb 包下下来,用dpkg -i或rpm -ivh装。我不建议在生产机上源码编译,除非你确实需要高于仓库版本的新特性。
2.2 第一条加压命令:让 CPU 满载并观察负载
安装完先跑一条最简单的命令:压 CPU 60 秒。这里我用 4 个 worker,你可以根据机器核心数调整:
stress --cpu 4 --timeout 60s--cpu 4会创建 4 个子进程,每个进程不断执行类似平方根计算的数学运算,把 CPU 跑满。--timeout 60s是安全阀,到时间自动退出,避免你忘了 Ctrl+C 导致机器长时间满载。
执行后,在另一个终端里用top观察:正常会看到 4 个 stress 进程占满 CPU 核心,系统 load average 快速爬升。比如 4 核机器,负载会跑到 4 左右。这里要注意:如果是在虚拟机或云主机上做测试,逻辑 vCPU 数量可能不等于物理核心数,stress 的 worker 是跑在逻辑 CPU 上的,后面第 5 章会细说。
2.3 确认压力是否真的生效:top、uptime、mpstat 怎么配合
压力测试最怕“你以为压了,其实没压”。只开一个 top,往往看不到全局。我通常会同时开三个视角:
top:看每个 stress 进程的 CPU 占用和系统 load average。uptime:看 1/5/15 分钟负载,确认压力是否持续。mpstat -P ALL 1:逐核心看占用率,确认压力分布是否均匀。
# 每 1 秒输出一次所有 CPU 核心的使用率 mpstat -P ALL 1如果只有某个核心 100%,其他核心空闲,说明 worker 数小于核心数,压力集中在部分核心上。要模拟整机满载,就要把 worker 数调到逻辑核心数。还有一个细节:load average 不只看 CPU,还包含不可中断睡眠的进程数。所以压磁盘时,哪怕 CPU 占用不高,负载也会走高,这点第 4 章会专门讲。
3. 加压测试的完整参数地图:CPU、内存、磁盘、IO 怎么组合
3.1 CPU 压力:worker 数与超线程的关系
CPU 压力是 stress 最常用的场景。--cpu N里的 N 表示 worker 数量,每个 worker 是一个独立进程。命令如下:
stress --cpu $(nproc) --timeout 10s --verbose$(nproc)会取当前机器的逻辑处理器数量。比如一台 4 核 8 线程的机器,nproc返回 8,stress 就会创建 8 个 worker,每个逻辑核心满载。这里有个容易误解的点:超线程只是让一个物理核心同时处理两个逻辑线程,stress 的 worker 计算密集型任务时,两个线程会争抢同一个物理核心的执行单元,所以如果目标是测试“每个物理核心峰值性能”,一个物理核心跑一个 worker 更接近真实;但如果是模拟高并发用户请求,按逻辑核心数压更常见。
--timeout 10s是强制结束时间,--verbose会输出每个 worker 的启动和退出信息。跑完你会看到进程退出后,CPU 占用立刻掉下来。如果发现--cpu 4跑出来的负载只有 3 左右,先别急着怀疑工具,去查一下是不是有系统服务在占用 cpu,或者 cpufreq 的节能策略把频率压低了。
3.2 内存压力:malloc 与 touch 的区别,为什么需要 --vm-bytes
内存压力用--vm和--vm-bytes配合。下面这条命令创建 2 个内存 worker,每个分配 512MB,分配后保持 10 秒:
stress --vm 2 --vm-bytes 512M --vm-hang 10 --timeout 60s--vm N表示同时有 N 个 worker 在做内存分配;--vm-bytes是每个 worker 分配的内存大小;--vm-hang让 worker 在分配后睡眠 N 秒,而不是立刻释放,这样内存压力能持续一段时间。
为什么强调--vm-bytes?stress 的内存 worker 会先调用 malloc 分配内存,然后遍历这块内存写入数据,也就是把页面真正“touch”到物理内存里。如果不指定--vm-bytes,默认每个 worker 只分配 256MB,压不出什么效果。另一方面,malloc 只是虚拟地址空间分配,不 touch 时物理内存占用很低,所以实际压的是物理内存,必须让它写页。
跑之前建议先看内存余量:
free -h如果--vm 2 --vm-bytes 8G加上系统本身占用已经超过物理内存,系统就会进入 swap 跌宕,甚至触发 OOM。这个翻车现场会在第 5 章详细讲。
3.3 磁盘与 IO:利用 stress 的 hdd 选项制造写风暴
stress 的磁盘压力通过--hdd实现。下面命令创建 2 个磁盘 worker,每个 worker 在同一目录下写 1GB 数据后删除,持续 30 秒:
mkdir -p /tmp/stress_dir && cd /tmp/stress_dir stress --hdd 2 --hdd-bytes 1G --timeout 30s--hdd N会启动 N 个 worker,每个 worker 执行“写入临时文件 → 调用 fsync → 删除文件”的循环。--hdd-bytes控制单次写入的数据量。要注意:stress 的 hdd worker 默认会在当前目录下创建临时文件,如果当前目录在根分区或数据盘上,高强度写会把磁盘带宽打满,甚至影响其他业务。常见做法是专门建一个/tmp/stress_dir或挂载一个独立的测试分区,避免把重要目录暴露给随机写。
另外,--io N是让 worker 执行 sync() 系统调用,会产生高 iowait,但实际数据写入量并不大。它的作用是制造“IO 等待态”,让 load average 升高,适合模拟大量进程等待磁盘的场景。组合使用时,我一般把--hdd和--io分开,一旦混在一起,很难判断是同步风暴还是写数据造成的卡顿。
3.4 组合参数:模拟真实高负载场景的常用配方
单资源压测能暴露“这个单一资源缺不缺”,但很多 linux 运维故障案例是资源争抢导致的,比如内存不够时 CPU iowait 升高,磁盘变慢时负载飙升。这时用组合参数更有效。下面是一个 5 分钟综合配方:
stress --cpu 4 \ --vm 2 --vm-bytes 1G \ --hdd 1 --hdd-bytes 1G \ --timeout 300s --verbose这条命令同时压 CPU、内存和磁盘。每条参数的逻辑是:--cpu 4占满 4 个逻辑核心;--vm 2用两个 worker 各分配 1G 内存;--hdd 1在后台做写文件循环。组合起来,系统各资源相互影响,比如磁盘慢会导致进程进入 D 状态,负载升高,从而暴露内核调度或 cgroup 限制的问题。
一个常见误区是把--cpu 4放到 2 核机器上跑,会让系统调度过载,负载虚高,压力测试结果不可比。我的经验是,先在单资源模式下把每一项跑通,记录基线数据,再组合测试。组合测试里每一项的参数要比单资源测试保守一点,比如内存用量只取可用内存的 50%,否则还没到真正的业务峰值,机器先被压死了。
4. 把 stress 的结果读成系统健康报告:从负载、响应时间到温度
4.1 负载 vs CPU 占用:别被 top 骗了
压测时,top 里 load average 数值最直观,但也最容易误导人。load average 统计的是处于 R(运行)和 D(不可中断睡眠)状态的进程数。stress 的--hdd会让进程频繁进入 D 状态等待磁盘,这时你看 CPU 占用很可能只有 20%,但 load average 却一路飙升到十几。
所以读完 top 后,至少要用mpstat -P ALL 1确认 CPU 占用分布,再用iostat或vmstat判断 D 状态是否来自磁盘。比如一条压测命令结束后,load average 还停在高峰,先别怀疑 stress,去查是不是磁盘队列里还有大量写请求没落盘。
另一个细节:load average 的 1 分钟值是短期波动,5 分钟和 15 分钟值才是长期趋势。压测时我会故意把--timeout设成 120 秒以上,压完后观察 5 分钟负载回落曲线。如果 15 分钟值仍然高于压测前的两倍,说明有残留进程或磁盘任务没有排空。
4.2 内存压力对系统性能的影响:swap 和 oom
内存压力不是单纯看 free 剩余多少,而是看 swap 和 oom 行为。压测时用 vmstat 观察 si/so 和 free 字段:
vmstat 1 30si和so表示从 swap 换入和换出的数据量。只要这两个值持续非零,说明系统已经出现内存回收和换页,这时候哪怕 free 显示还有几百 MB,实际响应速度也会明显变慢,因为 CPU 大量时间在等待换页。继续加大--vm-bytes,内核的 OOM killer 会介入,杀掉进程。可以从 dmesg 里看到具体被杀进程:
dmesg | grep -i oomOOM 不一定只杀 stress 的 worker,如果系统服务进程撞上 OOM,可能会被杀掉,这就是压测把自己的业务压挂了常见原因。所以在生产环境跑内存压力前,务必先看业务进程的 OOM 保护值(/proc/<pid>/oom_score_adj),不要让关键服务暴露在高风险下。
4.3 结合监控工具:用 vmstat、iostat、sar 记录压力过程
只看瞬时状态不够,压测需要留证据。我习惯把 vmstat、iostat、sar 同时跑起来,并把输出落到文件里,压测结束后再分析。示例:
vmstat 1 > /tmp/vmstat.log 2>&1 & VMSTAT_PID=$! iostat -x 1 > /tmp/iostat.log 2>&1 & IOSTAT_PID=$! stress --cpu 8 --vm 2 --vm-bytes 1G --timeout 120s kill $VMSTAT_PID $IOSTAT_PID说明:vmstat 1每秒输出一次系统内存、CPU、swap 状态;iostat -x 1每秒输出一次磁盘 util、await、svctm 等指标。stress 结束后,通过比对日志里的时间戳,能准确还原压力发起和释放的整个过程。
如果机器装有 sar,也可以直接用:
sar -u -r -d 1 > /tmp/sar.log 2>&1 &sar 的-u是 CPU,-r是内存,-d是磁盘。用日志文件的好处是,压测结束后可以反复查,不用盯着终端。
5. 避坑指南:stress 使用中的 5 个常见翻车现场
5.1 现象:SSH 断开、系统假死
原因:--cpu的 worker 数超过逻辑核心数太多,再加上--vm和--hdd的组合,CPU 长时间满载,系统软中断和网络处理跟不上,SSH 连接就被操作系统“甩掉”了。
解决:先把所有参数减半再跑。比如 4 核机器用stress --cpu 4 --timeout 30s,确认负载正常后再加其他参数。同时可以给 stress 进程设置较低优先级:
nice -n 10 stress --cpu 8 --timeout 60snice -n 10降低进程优先级,即使压力很大,SSH 和系统管理进程仍然能抢到 CPU。压测时最好额外留一个已经登录的本地 console,别只依赖 SSH。
5.2 现象:内存测试卡死,机器迟迟不响应
原因:--vm-bytes加得太大,超过了物理内存与 swap 的可用空间,系统不断换页,最终 OOM killer 直接冻结进程,或者把桌面/业务进程一起带走。
解决:压测前先free -h看可用内存,把--vm-bytes乘以 worker 数控制在可用内存一半以内。例如 16GB 内存的机器,跑 2 个 worker,每个 worker 设 4GB 已经是极限压测,初次尝试建议从 2GB 起步:
stress --vm 2 --vm-bytes 2G --timeout 60s如果想让压力更温和,加上--vm-hang 5,让内存 worker 保持分配后休息,而不是持续做分配释放,这样压力更平缓。
5.3 现象:磁盘测试写爆目录,或者文件系统报错
原因:--hdd会在当前目录生成临时文件,如果当前目录在数据盘上一只写到 fsync,文件系统或者磁盘被写穿,某些文件系统会报 I/O error。
解决:永远不要在生产目录下直接跑磁盘压力。先建一个独立目录或挂载测试分区,并把单次写入量控制住:
mkdir -p /mnt/test_stress && cd /mnt/test_stress stress --hdd 1 --hdd-bytes 1G --timeout 30s如果需要长时间压磁盘,建议用--hdd-bytes 64M这样的小尺寸,避免单次写满整个分区。压完以后第一时间检查临时文件是否清理干净,如果 stress 中途被 kill,临时文件可能残留。
5.4 现象:压测结果不可比,同一台机器两次负载值差很多
原因:两次压测之间,CPUFreq 调速器状态不同,机器可能处于 powersave 节能模式,或者温度过高触发了降频。
解决:压测前固定 CPU 频率。常见的做法是用 cpupower 把 CPU 调到 performance 模式:
cpupower frequency-set -g performance如果 cpupower 没装,用发行版包管理安装linux-cpupower。另外记录环境温度,散热不好的机器在压测后期频率会下降,负载可能比刚启动时低,这不算工具问题,是散热问题。要让结果可对比,最好同一环境、同一模式、同一持续时间。
5.5 现象:Ctrl+C 后负载不降,stress 进程还在
原因:stress 的信号处理会把 SIGINT 发给所有 worker,但如果你用了 shell 管道、nohup 或 systemd 启动子进程,信号可能没传递到全部 worker,残留的 worker 继续消耗 CPU。
解决:用--timeout让 stress 自己优雅退出,而不是依赖 Ctrl+C。如果已经残留,直接清理:
pkill -u root stress如果是你自己的用户跑的,用pkill stress即可。压测完再执行uptime确认负载回落,不要急着离开终端。
6. 把 stress 用出工程价值:脚本化、限时自动降载与真实负载模拟
6.1 封装一个带安全阀的综合加压脚本
单次命令只适合临时试验,巡检、验收、比对硬件时要做成脚本。下面这个脚本用当前系统负载倒推出资源用量,并固定压测时长:
#!/bin/bash set -e # 根据可用内存的 25% 计算每个 vm worker 的分配量 AVAIL_MB=$(free -m | awk '/Mem:/{print $7}') VM_WORKERS=2 VM_BYTES=$((AVAIL_MB * 1024 * 1024 / 4 / VM_WORKERS)) CORES=$(nproc) echo "CPU workers: $CORES" echo "Each VM worker: $((VM_BYTES / 1024 / 1024)) MB" stress --cpu "$CORES" \ --vm $VM_WORKERS --vm-bytes "$VM_BYTES" \ --hdd 1 --hdd-bytes 512M \ --timeout 300s --verbose这个脚本先读环境,再组合压测。AVAIL_MB取 free 的 available 字段,然后除以 4 再除以 worker 数,保证内存压力只占可用内存的 25%,不会把机器压到 OOM。压测结束后,配合dmesg | tail -50检查内核日志有没有硬件错误或 OOM 记录,这是比纯看负载更硬核的验证方式。
6.2 结合 systemd 跑定期巡检,压完必须自动降载
如果你要周期性检查机器是否还能扛住峰值负载,不建议直接 cron 跑 stress,而是写一个 systemd service,启动后自动压测,压测结束后强制退出并记录状态。
下面是一个简化的 service 脚本思路:在 ExecStart 里调用上面那个脚本,但把--timeout设为 600s,然后通过 systemd 的TimeoutStopSec=60s防止进程挂死。核心原则就一条:压测必须有限时、有退出路径、有日志,否则就是在给自己埋雷。
6.3 验证、核对、形成习惯
压测不是跑完就结束。我习惯压测前后各记录一份lscpu、free -h、uptime和磁盘iostat,压测结束后对比这两份数据。如果负载回落慢,先查进程;如果 dmesg 有硬件错误,先换内存或磁盘再谈调优。这比盯着 top 的瞬时值有用得多。做运维这些年,最大的教训是:压力测试不是用来折磨机器的,而是让你在真实故障来临之前,提前找到系统的短板。希望帮到你。
本文还有配套的精品资源,点击获取