简介stress 是 Linux 平台上一款经典的系统压力测试工具围绕 CPU 计算、内存读写等场景模拟高负载帮助系统管理员、运维工程师和开发者评估硬件稳定性、定位潜在瓶颈也适合在学习 Linux 性能调优时实践使用。该包对应 stress 1.0.1 源码共 32 个文件主要为 Makefile 构建脚本、configure 配置脚本、stress.c 主程序、texinfo 文档和 README 说明压缩包仅 199KB结构精简便于阅读改造。资源目前已有 1036 人学习。通过源码可理解多线程 CPU 加压、内存分配与读写测试的具体实现掌握 --cpu、--vm、--vm-bytes 等参数的底层行为结合 top、vmstat 等监控工具还能深入观察系统在压力场景下的资源变化为后续调优、故障排查或定制压测工具提供清晰参考。1. 压测不是把 CPU 打满就收工linux stress加压测试工具的真实用法很多刚接触 Linux 压测的人第一反应就是丢一条stress --cpu 8 --timeout 60看着 CPU 冲到 100% 就截图收工结果系统上线后照样出幺蛾子。真正能拿来评判稳定性的压测核心不在“满载”而在加载方式是否贴合真实流量、观测指标是否对得上资源瓶颈、退出条件是否可控。这套 linux stress加压测试工具包把 stress、stress-ng、fio、iperf3 的实测参数、组合模板和踩坑记录收在一起适合新手照抄参数跑一遍完整流程也适合老手在封装脚本时对比边界条件少走弯路。2. 选型与部署stress、stress-ng、sysbench、fio 怎么分工2.1 压测工具不是通用件先按资源大类选型压测工具不能混用这是最容易被忽略的一点。很多人拿 stress 测磁盘测完一看 IO 指标挺高实际业务照样卡原因是 stress 的磁盘模块只是普通文件写不产生真实的磁盘队列行为又比如用 sysbench 测 CPU它走 pthread 多线程结果受调度器影响很大。所以动手之前先把工具的服务对象理清楚。我通常按资源类型做如下的分工这也决定后续参数模板怎么选工具压测对象主要能力适用场景stressCPU/内存/IO基础加压语法简单快速冒烟测试stress-ngCPU/内存/进程/链路300 压测模块支持超时和故障注入稳定性验证主力sysbenchCPU/内存/文件/数据库基准跑分和前后对比性能基线对比fio磁盘 IO多引擎、多读写模式、队列深度可调存储性能验证iperf3网络带宽TCP/UDP 多流、反向测试链路与网卡验证对大部分稳定性测试场景主推 stress-ng fio iperf3sysbench 专门用来在压测前后做性能基线。选型错的典型后果就是stress 的 hdd 模块压出来的磁盘「性能很好」换到真实业务用就直接崩盘数据完全不可信。2.2 安装与部署包管理器、离线环境与版本核对在联网环境下安装用包管理器一条命令就能完成。Debian/Ubuntu 系和 RHEL/CentOS 系的命令稍有差异# Debian / Ubuntu 系 apt-get update apt-get install -y stress stress-ng sysbench fio iperf3 # RHEL / CentOS 系部分源里没有 stress直接用 stress-ng yum install -y epel-release yum install -y stress-ng sysbench fio iperf3如果机器在内网环境常见的做法是在一台能联网的同架构机器上把依赖包拉下来再拷贝进内网安装# 在线机器上拉取全部依赖到 /tmp/pkgs yumdownloader --resolve --destdir/tmp/pkgs stress-ng fio iperf3 # 拷到内网机器后批量安装 rpm -ivh /tmp/pkgs/*.rpmDebian 系也有类似的 apt-get download 加 dpkg -i 的路线但依赖关系要自己逐一核对rpm 系用 yumdownloader --resolve 更省事。装完之后一定要核对版本参数在不同小版本间有细微差异网上很多旧文章的参数表不能直接照抄以你当前环境里stress-ng --version、fio --version、iperf3 --version的输出为准。2.3 资料包里预先拆好的脚本骨架这套资料包里预置了一个可直接用的脚本骨架目录结构如下linux-stress-toolkit/ ├── run_stress.sh # 统一入口按场景调用 ├── conf/ │ ├── preset_cpu.conf # CPU 场景预设参数 │ ├── preset_mem.conf # 内存场景预设参数 │ ├── preset_disk.conf # 磁盘场景预设参数 │ └── preset_net.conf # 网络场景预设参数 ├── scripts/ │ ├── collect_metrics.sh # 压测时采集 top/vmstat/sar 数据 │ └── check_env.sh # 检查工具是否安装、目录是否可写 ├── logs/ # 压测日志统一落这里 └── docs/ ├── 参数速查.md └── 踩坑记录.md用法上新手拿到后先跑check_env.sh做环境自检再按场景跑run_stress.sh cpu 120或run_stress.sh disk 300不需要从零敲参数。老手可以直接改 conf 里的值比如把preset_disk.conf里的块大小从 4k 改成 64k去模拟大文件顺序读场景。日志全部落到带时间戳的目录里防止轮次之间互相覆盖。3. CPU 与内存加压实操用 stress-ng 压满核、触发 OOM参数逐个拆3.1 CPU 压测--cpu、--cpu-method、--timeout 的组合规则CPU 压测最常用的场景是验证多核调度和长时间高负载下的稳定性。先看一条基础命令# 压满 4 个物理核心用矩阵乘法压 FPU60 秒后自动退出 stress-ng --cpu 4 --cpu-method matrixprod --timeout 60s --metrics-brief --times--cpu 4表示起 4 个 CPU worker 进程这个值不是随便填的。在物理 4 核机器上刚好打满在开了超线程的 8 线程机器上则会留下 4 个硬件线程空闲负载形态和预期不一样。我一般先lscpu看物理核数再决定 worker 数量。--cpu-method matrixprod指定用矩阵乘法做计算对 FPU 和缓存的压力更集中想看 CPU 整数运算能力可以换成primes想模拟服务端常见计算负载可以用ackermann。不同算法对 ALU、FPU、缓存带宽的消耗比例不同选哪个取决于你想压什么。--timeout 60s是压测自动结束时间单位支持 s、m、h、d生产环境这个参数必须写否则很容易压上就忘记停。--metrics-brief在结束时输出一次汇总指标--times额外输出 user 和 sys 耗时占比用来判断系统是否出现大量内核态开销。压测过程中判读是否正常用mpstat -P ALL 1看每个核的%usr全部接近 100 且%sys很低是正常状态如果%sys比例异常高说明压测负载触发了系统调用或内部锁竞争需要进一步排查。watch -n 1 cat /proc/loadavg可以看到 load 是否接近核数。注意 stress-ng 结束时报的 bogo ops/s 只能用于同机器前后对比跨机器比绝对值没有意义。3.2 内存压测与 OOM--vm-bytes 用百分比比绝对值更安全内存压测最容易翻车的地方是写死内存大小。一台 8G 的机器和一台 64G 的机器同样写--vm-bytes 1G压力差了 8 倍。用百分比可以避免这个坑# 压 2 个内存 worker每个拿系统内存的 40%分配后挂 5 秒再继续 stress-ng --vm 2 --vm-bytes 40% --vm-hang 5 --timeout 120s --metrics-brief--vm 2是内存 worker 数--vm-bytes 40%表示每个 worker 分配总内存的 40%也可以写512M这种绝对值。--vm-hang 5是指分配完成后挂起 5 秒模拟常驻内存的场景不加--vm-hangworker 分配完立刻返回负载形态完全不一样测出来的内存压力不具备参考价值。两条命令的总分配量是2 x 40% 80%这对大多数应用已是高水位。如果想故意触发 OOM 场景把分配总量超配到 128%# 总量超配内核 oom killer 会介入用于验证系统在极端内存下的表现 stress-ng --vm 3 --vm-bytes 128% --timeout 60s --oom-avoid--oom-avoid是让 worker 在接近 OOM 边界时自动调整自身占用避免直接把自己刷死。OOM 之后看内核日志dmesg -T | grep -i oom建议内存压测前先确认/proc/sys/vm/overcommit_memory的当前值值为 0 时内存耗尽会触发 oom killer值为 2 时分配直接失败根本到不了 OOM 流程。生产环境不要直接打 128%先用 75% 观察水位确认内存回收行为后再决定要不要做故障注入。3.3 组合加压CPU、内存、fork 一起上暴露隐藏瓶颈单类负载容易掩盖系统短板组合负载才是接近真实流量的方式。下面这条命令同时压 CPU、内存和进程表# 4 核 CPU 2 个内存 worker 4 个 fork 子进程300 秒后退出 stress-ng --cpu 4 --vm 2 --vm-bytes 50% --fork 4 --timeout 300s --metrics-brief --times--fork 4是不断创建并退出子进程给进程管理带来压力。当 CPU 和内存已经紧张时再叠加 fork 负载能暴露资源泄露和调度陷阱。压测时配合vmstat 1 3观察cs上下文切换、si/soswap in/out如果so持续大于 0说明内存已经溢出到 swap系统整体性能会断崖式下跌。再深一步可以用top按 TIME 排序看哪个进程吃 CPU 最凶判断系统有没有异常内核线程在抢时间片。3.4 stress-ng 常用参数速查下面的参数表覆盖了 80% 的日常压测需求可以贴在终端旁边对照用参数作用常用值--cpuCPU worker 数等于物理核数--cpu-methodCPU 压测算法matrixprod / primes / crc16--vm内存 worker 数2 ~ 4--vm-bytes每个 worker 分配内存1G / 40% / 128%--vm-hang分配后挂起秒数5 ~ 10--fork子进程负载4 ~ 8--timeout压测总时长60s / 300s / 1h--metrics-brief输出汇总指标常驻参数--oom-avoid自动调整内存避开 OOM与故障注入互斥需要留意的是老版 stress 同样有--cpu、--vm、--timeout但不支持--cpu-method、--metrics-brief。网上大量 stress 参数表直接照搬到 stress-ng 上一半能跑一半直接报错凡是涉及 CPU 算法和汇总输出的地方必须区分版本再执行。4. 磁盘与网络压测fio、iperf3 配置模板与业务场景的差距4.1 fio 随机读基准direct、ioengine、iodepth 决定结果可信度磁盘压测里 fio 是事实标准但同样一套参数不同人跑出来的结果可能差一个数量级。问题往往出在direct、ioengine、iodepth这三个参数上。以模拟数据库日志文件的 4K 随机读为例fio --namerandread \ --directory/data/pressure \ --filenameloadtest.dat \ --ioenginelibaio \ --direct1 \ --rwrandread \ --bs4k \ --size4G \ --numjobs4 \ --iodepth32 \ --runtime120 \ --time_based \ --group_reporting--direct1绕过页缓存直接发 I/O 给设备测的是真实存储能力想测文件系统缓存性能时去掉它但两种数据不能混着对比。--ioenginelibaio是 Linux 异步 I/O配--iodepth32表示内核队列深度 32模拟真实并发。新内核也可以用io_uring引擎但需要对齐内核版本和 fio 版本。--rwrandread是随机读顺序读用--rwread顺序写用--rwwrite混合负载用--rwrandrw并加--rwmixwrite50控制比例。--bs4k是块大小。数据库在线日志常用 4k~16k文件服务常用 64k~128k块大小和业务不对应时数据没有参考价值。--size4G是每个 job 的文件大小--numjobs4时总占用 16G要确认磁盘剩余空间。--runtime120 --time_based是固定压测时长而不是跑完文件就跑否则 4G 文件几分钟跑完结果不稳定。结果判读看三列bw带宽、iops、clat的avg和p99。99 分位延迟比平均延迟更能反映排队情况单独报告 iops 不讲块大小和读写模式基本等于没报。4.2 fio 随机写测试预分配文件避免性能衰减误判随机写比随机读更吃磁盘测试参数也要更谨慎fio --namerandwrite \ --filename/data/pressure/write.dat \ --ioenginelibaio \ --direct1 \ --rwrandwrite \ --bs4k \ --size4G \ --numjobs2 \ --iodepth16 \ --runtime120 \ --time_based \ --fallocateposix \ --group_reporting--fallocateposix预先分配文件空间避免测试过程中因文件分配产生的写性能抖动。磁盘剩余空间要大于size x numjobs否则直接报 no space。结果里写延迟比读高一个数量级是正常的但如果出现延迟尖刺立即配合iostat -x 1看%util和avgqu-sz判断设备是否已经饱和。注意 fio 结果与文件系统、设备类型强相关同一套参数在 HDD 上 200 IOPS在 NVMe 上可能几千。跨设备对比没有意义正确的做法是在目标机器上先跑一轮基线再跑加压轮两次之间只改业务变量其它保持不动。4.3 iperf3 网络带宽先看单流再看多流别拿单流当上限网络压测的起步是 iperf3。服务端和客户端分别执行# 服务端监听 5201日志写入文件避免窗口刷屏 iperf3 -s -p 5201 --logfile /var/log/iperf3_server.log# 客户端4 条并行流压 30 秒TCP 模式 iperf3 -c $SERVER_IP -p 5201 -t 30 -P 4 -b 200MTCP 模式下-b不填更利于系统自动协商带宽填了反而可能成为瓶颈UDP 模式下-b必填否则只发极小的流量测不出链路。-P 4起 4 条并行流用于验证多流扩展性。看结果时 TCP 主要看Retr重传和每流带宽UDP 要看Jitter和Lost/Total Datagrams。如果多流比单流提升明显说明单核收包能力是瓶颈如果多流几乎不增长检查网卡多队列和中断亲和配置。常见误用是直接在两端起默认参数拿单个 TCP 流的吞吐代表整条链路。单流受单核收包限制根本跑不出链路上限。正确顺序是先单流测基线再-P 4、-P 8看扩展趋势最后用 UDP-b打目标速率观察丢包率。4.4 磁盘和网络组合加压一把梭才能看出资源抢占容器和虚拟化环境经常出现磁盘 IO 抢占 CPU 中断导致网络吞吐下降的问题。要复现这种场景把 fio 放后台iperf3 放前台同时跑# 后台跑磁盘 4K 随机读 fio --namecombo_randread \ --filename/data/pressure/combo.dat \ --ioenginelibaio \ --direct1 \ --rwrandread \ --bs4k \ --size4G \ --numjobs4 \ --iodepth32 \ --runtime60 \ --time_based \ --group_reporting \ --output/tmp/fio_combo.log # 前台跑网络带宽测试 iperf3 -c $SERVER_IP -p 5201 -t 60 -P 4 wait这个组合能模拟数据库双写同时跑数据迁移的场景。对比单独压测时的数据两个指标掉得越多说明机器资源越紧张业务上需要做资源隔离或调度优化。5. 避坑stress 加压测试中的 5 个常见翻车点与排查方法这份清单来自实际压测中反复踩过的坑每一条按现象、原因、处理三步记录适合在现场排查时直接对照。5.1 SSH 断连、系统假死压测把调度通道也打满了现象压测开始几分钟后远程操作逐渐卡顿ssh 敲命令没有响应最终直接断开。原因CPU 全部核心被占满后sshd 进程和你的 shell 进程一起排队等待调度如果同时开大内存分配swap 反复换页IO 也被拖住整个系统看起来像死机。处理所有压测命令先在 tmux 里启动占住一个随时可恢复的会话压测命令必须带--timeout避免失控如果想留管理通道用taskset把 sshd 或 shell 绑定到一个空闲核上或者直接把--cpuworker 数设为物理核数减一。出现假死时不要急着按重启先等待 swap 换页完成5 到 10 分钟后再操作往往能恢复。5.2 OOM 杀了一半进程剩余进程还在反复拉起现象dmesg出现 Out of memory系统卡顿但业务进程杀不干净top 里的进程 ID 反复变化。原因压测触发 oom killer 后被杀的进程如果有守护组件自动拉起就会进入分配内存、被杀、重启的循环另一种可能是 overcommit 配置导致分配失败后应用自行重试。处理先dmesg -T | grep -i oom找到被杀的进程再查它是被 systemd 还是托管服务拉起的。临时停掉对应服务的自动重启或者调整/proc/pid/oom_score_adj把压测 worker 的优先级抬高让 oom killer 先杀压测进程而不是业务进程。生产环境不要大范围触发 OOM压测务必在资源隔离的机器或容器里做。5.3 fio 测出来 iops 很高业务场景依旧慢现象fio 随机读测出几千 iops拿报告去对照业务压测业务场景照样慢。原因fio 参数和业务负载不匹配。比如只测了 128k 顺序读业务实际是 4k 随机写或者没开--direct测出来的是页缓存而不是存储设备又或者队列深度太浅没有模拟多线程场景。处理业务是什么 IO 特征就照实配。数据库日志优先用 4k 随机写加--iodepth32跑一轮对象存储再叠加 128k 顺序读。判断时看clat的p99和max而不是只看平均延迟。压测前先跑一个无业务干扰的基线再把新负载和基线对比中间不要混入其它变更。5.4 压测停了load average 还在高位警告现象压测进程已经退出但top里 load average 依然很高持续几分钟甚至十几分钟。原因部分 worker 进程进入 D 状态不可中断睡眠在等磁盘或网络 IO或者压测产生的子进程有残留也可能是 IO 请求队列里还有大量排队没有清空。处理用ps -eo pid,ppid,stat,cmd | grep -E D|stress|fio找出残留进程确认压测进程确实退出后再处理。配合iostat -x 1看%util和avgqu-sz等队列自然排空。这个现象在 HDD 压测后最常见SSD 上会快很多如果是内核模块的 IO 卡死导致 D 状态进程长时间不退重启机器最干净。5.5 同一台机器跑两遍结果相差 20% 以上现象同一套参数连续跑两次iops 差异明显数据看起来很不稳定。原因后台有定时轮转日志、备份任务同盘有其它进程在写CPU 频率调度策略不一致任何一个因素都会让结果漂移。处理压测前关掉无关 cron 任务用taskset -c绑定相同的 CPU 集合临时把 CPU 调速器切到 performance 模式连续跑 3~5 轮取中位数或最小值不要取平均值。压测报告里附上环境参数包括 CPU 频率策略、IO 调度器、内核版本否则结果无法复现。6. 进阶把压测固化成一个自动化脚本用退出码和日志控制验证节奏6.1 脚本骨架入口统一超时写死把压测流程封装成脚本最大的价值不是省敲几条命令而是让每一次压测的环境检查、参数来源、日志落盘和退出状态都可追溯。下面是一个能直接落地的骨架#!/bin/bash set -uo pipefail SCENARIO${1:-cpu} DURATION${2:-120} BASE_DIR$(cd $(dirname $0) pwd) CONF_DIR$BASE_DIR/conf LOG_DIR$BASE_DIR/logs/$(date %Y%m%d_%H%M%S) mkdir -p $LOG_DIR $BASE_DIR/scripts/check_env.sh || exit 2 case $SCENARIO in cpu) stress-ng --cpu 4 --cpu-method matrixprod \ --timeout ${DURATION}s --metrics-brief --times \ $LOG_DIR/cpu.log 21 ;; mem) stress-ng --vm 2 --vm-bytes 50% --vm-hang 5 \ --timeout ${DURATION}s --metrics-brief \ $LOG_DIR/mem.log 21 ;; disk) fio --nameauto_disk \ --filename/data/pressure/auto.dat \ --ioenginelibaio --direct1 \ --rwrandread --bs4k --size2G \ --numjobs4 --iodepth32 \ --runtime$DURATION --time_based --group_reporting \ --output$LOG_DIR/disk.log ;; *) echo usage: $0 cpu|mem|disk [seconds] exit 1 ;; esac rc$? echo scenario$SCENARIO rc$rc $LOG_DIR/run.summary vmstat 1 3 $LOG_DIR/vmstat_after.log exit $rc逻辑说明set -uo pipefail开启未定义变量报错和管道失败检测比set -e更适合压测因为压测工具返回非零可能不是崩溃而是预期内的业务失败需要保留退出码让上层自行判断。BASE_DIR用dirname定位脚本目录避免从其它路径调用时找不到脚本和配置文件。每轮压测都新建带时间戳的日志目录这是防止覆盖上一轮数据的关键做法。check_env.sh返回非零时脚本立即以退出码 2 结束区分环境问题和测试失败。6.2 结果判断与退出码先看压测是否被中断再判数据压测工具正常完成时退出码为 0被信号中断或参数错误时返回非 0。脚本把退出码写进run.summary在汇总多个场景时能一眼区分正常完成和中途中断。我自己的判断规则是退出码为 0 且日志里出现 successful 关键字的才算有效数据出现 Out of Memory 的单独标记为异常场景被 timeout 杀掉的非 0 退出数据不进对比集合。提前定义好这套规则可以避免把无效数据写进压测报告这个细节决定了报告的专业程度。6.3 压测结束后的快速验证用 sysbench 跑一轮前后对比压测分两种目的稳定性验证看压测过程有没有报错性能基准验证要在压测前先跑 sysbench 基线压测后再跑一轮对比事件吞吐变化是否在可接受范围sysbench cpu run --threads4 --time10 --events10000磁盘用 fio 同参数前后对比网络用 iperf3 连续跑三次取中位数。验证的核心是控制变量两次之间不更换内核参数、不重启服务。压测报告附上基线值和调优命令其它人拿到能直接复现。我之前在某次发布前的压力验证里图省事没给压测写--timeout结果测试跑了一整晚第二天早上 12 个核全部 100%OOM 日志刷屏连排查命令都按不动。从那以后我每次压测都强制走脚本入口先把超时写死再核对退出码和日志目录最后才安排测试窗口。希望帮到你。本文还有配套的精品资源点击获取