ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Linux stress 压测实战:CPU、内存、IO 混合场景与避坑指南

Linux stress 压测实战:CPU、内存、IO 混合场景与避坑指南 简介stress 是 Linux 平台上一款经典的开源压力测试工具面向系统管理员、运维工程师与内核调优爱好者用于在受控环境下模拟 CPU、内存、进程与线程的高负载场景评估系统极限性能与稳定性。本资源为 stress-1.0.1 源码包共 32 个文件压缩包约 199KB包含 configure 构建脚本、stress.c 核心源码、Makefile 系列编译文件、README/INSTALL 说明文档以及 texinfo 手册与 man 手册等覆盖从编译安装到参数使用的完整链路。已有 3079 人学习下载适合希望深入理解压力测试原理、自行编译定制或研究其实现细节的读者。通过阅读源码与文档可掌握 CPU 线程压测、内存分配与释放、进程创建销毁等核心逻辑并配合 top、vmstat 等工具观察系统在高负载下的表现为性能调优与稳定性排查提供参考。1. stress 压测到底在压什么从一次 CPU 飙到 800% 的线上排查说起线上告警说某台 4 核机器 load average 冲到 32登录一看top里八个stress进程把 CPU 吃得干干净净。这不是故障是我自己压的。stress这个工具在 Linux 圈子里算老面孔了它不测磁盘 IOPS不测网络吞吐专门干一件事按你指定的方式把系统资源吃到某个水位然后看系统在高负载下会不会崩、会不会变慢、会不会触发 OOM。它解决的是「我的服务在极限情况下还稳不稳」这个问题适合运维、后端、嵌入式 Linux 开发者做容量验证和故障复现。很多人第一次接触它是因为面试题里问「怎么模拟 CPU 满载」但真正用起来参数组合和观测方法才是分水岭。下面按「它怎么工作 → 怎么装怎么跑 → 参数怎么调 → 坑在哪 → 怎么进阶」的顺序讲透。2. stress 的工作模型与安装选型为什么它比 dd 和 yes 更适合做压测2.1 stress 的进程模型fork 出一堆 worker 各自干活stress的核心逻辑很朴素你告诉它要几个 CPU worker、几个 IO worker、几个 VM worker它就fork()出对应数量的子进程每个子进程进入一个死循环按类型执行不同的系统调用。CPU worker 做的是sqrt()运算IO worker 做的是write()和unlink()VM worker 做的是malloc()后反复读写内存页。父进程负责监控子进程状态收到信号后统一回收。这个模型决定了它的两个特点。第一压测强度是「进程数 × 单进程负载」不是百分比所以你在 8 核机器上跑--cpu 4和 4 核机器上跑--cpu 4对系统的影响完全不同。第二它不关心业务逻辑只关心系统调用层面的资源消耗所以用它压出来的结果反映的是内核调度和内存管理的极限不是你的应用在真实流量下的表现。想测应用层得用wrk、ab那类工具stress的定位是系统级基线。2.2 安装包管理器一条命令但要注意版本差异主流发行版仓库里都有stress安装本身没有难度# Debian/Ubuntu 系 sudo apt update sudo apt install -y stress # RHEL/CentOS/Rocky 系 sudo yum install -y epel-release sudo yum install -y stress # 验证安装与版本 stress --version逻辑说明stress在 EPEL 源里CentOS 最小化安装默认没有 EPEL所以要先装epel-release。--version输出的是版本号老版本如 1.0.4和新版本如 1.0.7在参数支持上有差异比如--vm-bytes的默认值不同压内存时如果不显式指定结果会不一致。参数说明-y表示自动确认-q可以静默安装减少输出。如果你在容器里装注意基础镜像可能是alpine需要用apk add stress但 alpine 仓库里的版本可能更老建议先stress --version确认。2.3 和 dd、yes、md5sum 压测的差别有人用yes /dev/null压 CPU用dd if/dev/zero of/tmp/test bs1M count10000压 IO。这些土办法能用但有几个硬伤。yes只能压单核想压多核得手动起多个进程再手动 kill没有统一的超时控制。dd压 IO 时如果没加oflagdirect数据会走页缓存压出来的 IO 曲线是假的。stress把这些封装成了参数--timeout控制持续时间--cpu N控制并发数--hdd配合--hdd-bytes控制写入量而且它会在结束后自动清理临时文件。做可重复的压测用stress比手搓命令靠谱。3. 用 stress 跑通四类压测CPU、内存、IO、混合场景的命令与观测3.1 CPU 压测指定核数与超时配合 mpstat 看每核负载最常用的场景是验证多核 CPU 在满载时的调度表现# 启动 4 个 CPU worker持续 60 秒输出详细日志 stress --cpu 4 --timeout 60s --verbose # 另开一个终端每秒采样一次所有 CPU 的使用率 mpstat -P ALL 1逻辑说明--cpu 4会 fork 出 4 个进程每个进程绑定一个逻辑核跑满。--timeout 60s让 stress 在 60 秒后自动退出避免忘记 kill 导致机器一直高负载。--verbose会打印每个 worker 的启动和结束信息方便确认实际起了几个进程。mpstat -P ALL 1每秒输出一行%usr列接近 100 说明该核被吃满%idle接近 0 说明没有空闲。参数说明--cpu后面的数字建议不要超过nproc的输出值超了会导致进程在核间频繁切换load average 虚高但实际吞吐不增。--timeout支持s、m、h、d单位不写单位默认秒。如果只想压特定核用taskset -c 0,1 stress --cpu 2把 stress 绑到 0 和 1 号核上。3.2 内存压测vm 与 vm-bytes 的配合盯紧 OOM killer内存压测比 CPU 危险因为分配过量会触发 OOM可能杀掉你的业务进程# 启动 2 个 VM worker每个分配 512M持续 120 秒 stress --vm 2 --vm-bytes 512M --timeout 120s --verbose # 另开终端观察内存和 OOM 事件 free -m dmesg -w | grep -i oom\|killed process逻辑说明--vm 2起两个进程每个进程通过malloc()申请--vm-bytes指定的内存然后反复写入数据触发缺页中断和物理页分配。free -m里看available列如果降到接近 0说明内存压力到位了。dmesg -w实时跟踪内核日志一旦出现Out of memory: Killed process说明压过头了。参数说明--vm-bytes支持K、M、G后缀默认单位是字节。总内存消耗约等于vm 数量 × vm-bytes但实际会略高因为进程本身还有栈和代码段开销。建议总分配量不超过available内存的 80%留出余量给系统。如果要做 OOM 测试可以故意超过但要确保机器上没有关键业务或者用 cgroup 限制 stress 的内存上限。3.3 IO 压测hdd 与 hdd-bytes 控制写入量iostat 看 awaitIO 压测主要验证磁盘在持续写入下的响应延迟# 4 个 IO worker每个写 256M 临时文件持续 90 秒 stress --hdd 4 --hdd-bytes 256M --timeout 90s --verbose # 另开终端观察磁盘指标 iostat -x 1逻辑说明--hdd 4起 4 个进程每个进程在/tmp下创建临时文件并反复写入、删除。--hdd-bytes控制每个进程写入的数据量。iostat -x 1每秒输出扩展统计重点看%util设备利用率和await平均等待时间。%util接近 100 说明磁盘饱和await飙升说明 IO 队列积压。参数说明--hdd的写入路径默认是当前目录建议先cd /tmp再执行避免污染工作目录。如果磁盘是 SSD%util可能不会到 100因为 SSD 的并行度高这时候看await和r/s、w/s更有意义。--hdd-bytes设太小会导致进程频繁创建删除文件压出来的是元数据操作而不是数据写入建议至少 128M 起步。3.4 混合压测同时压 CPU 和内存观察系统整体表现真实场景往往是多种资源同时吃紧混合压测更接近线上故障# 2 个 CPU worker 2 个 VM worker各 256M 2 个 IO worker stress --cpu 2 --vm 2 --vm-bytes 256M --hdd 2 --hdd-bytes 128M --timeout 180s --verbose # 综合观测 vmstat 1 10逻辑说明这条命令同时启动 6 个 workerCPU、内存、IO 三线并进。vmstat 1 10每秒采样一次共 10 次重点看r运行队列长度、si/so换入换出、waIO 等待占比。如果r持续大于 CPU 核数说明 CPU 是瓶颈如果si/so不为零说明内存不够开始用 swap性能会断崖式下跌。参数说明混合压测的 worker 总数建议不超过nproc × 2否则进程调度开销会掩盖真实瓶颈。--timeout设长一点比如 180 秒让系统有足够时间进入稳态。观测时先看vmstat的全局指标发现异常再用pidstat定位到具体进程。4. stress 压测的避坑与排查五个血泪教训4.1 压测把 SSH 压断机器失联现象跑stress --cpu $(nproc)后 SSH 卡死命令敲不进去只能硬重启。原因所有 CPU 都被 stress 占满sshd 进程抢不到时间片网络中断处理也被延迟。解决永远留一个核给系统用--cpu $(( $(nproc) - 1 ))。更稳妥的做法是用nice降低 stress 优先级nice -n 19 stress --cpu $(nproc)这样 sshd 能优先获得调度。4.2 内存压测触发 OOM业务进程被误杀现象stress --vm 4 --vm-bytes 2G跑了几秒MySQL 进程消失日志里出现Killed process。原因stress 申请的内存超过了系统可用内存内核 OOM killer 按评分选择牺牲品业务进程因为占用内存多被选中。解决压测前用free -m确认available值总分配量控制在 70% 以内。如果必须压到极限用 cgroup 把 stress 限制在独立的内存组里systemd-run --scope -p MemoryMax2G stress --vm 2 --vm-bytes 1G这样 OOM 只会杀 stress 自己。4.3 IO 压测把磁盘写满系统无法启动现象stress --hdd 8 --hdd-bytes 10G跑完发现/tmp满了重启后系统卡在登录界面。原因stress 异常退出时临时文件没清理干净或者--hdd-bytes设得太大把根分区写满。解决压测前用df -h确认目标分区剩余空间--hdd-bytes乘以 worker 数不要超过剩余空间的 50%。压测后手动检查ls /tmp | grep stress并清理。更安全的做法是把临时目录挂到独立分区或 tmpfs 上。4.4 容器里跑 stress 压的是宿主机现象在 Docker 容器里跑stress --cpu 4容器内top看到 4 个进程但宿主机 load 飙升其他容器变慢。原因容器默认共享宿主机的 CPU 资源没有做 cgroup 限制stress 消耗的是宿主机的核。解决启动容器时加--cpus2限制 CPU 配额或者用--cpu-shares设置相对权重。压测前用cat /sys/fs/cgroup/cpu.max确认容器的 CPU 上限确保 stress 的 worker 数不超过配额。4.5 压测时间设太长忘记加 timeout现象下班前跑了个stress --cpu 8没加--timeout第二天上班发现机器还在满载风扇狂转。原因stress 默认无限期运行不加--timeout就会一直跑下去。解决养成习惯任何 stress 命令都带--timeout哪怕设个1h也比不设强。如果已经忘了用pkill stress或killall stress快速清理然后uptime确认 load 回落。5. 进阶用 stress-ng 补位和写可复现的压测脚本stress本身功能有限不支持网络压测、不支持指定 CPU 亲和性、不支持统计报告。做更细的压测我一般会切到stress-ng它是 stress 的超集参数更丰富# 安装 stress-ng sudo apt install -y stress-ng # 压 4 个核每个核跑不同的算法持续 60 秒输出统计 stress-ng --cpu 4 --cpu-method all --timeout 60s --metrics-brief # 压网络启动 2 个 TCP 客户端和 2 个服务端走本地回环 stress-ng --sock 2 --timeout 60s --metrics-brief逻辑说明--cpu-method all让每个 worker 轮流使用不同的计算模式如sqrt、trig、bitops比 stress 单一的sqrt更能暴露 CPU 的浮点、整数、分支预测等不同单元的瓶颈。--metrics-brief在结束后输出每个 worker 的吞吐量bogo ops/s方便对比不同配置下的性能差异。--sock是 stress 没有的能压本地网络协议栈。参数说明--cpu-method可选值有all、sqrt、trig、bitops、matrix等all最全面但耗时最长。--metrics-brief输出的是 bogo ops不是标准单位只用于横向对比不要当成绝对性能指标。写可复现的压测脚本关键是把参数、观测命令、清理逻辑都固化下来#!/bin/bash # stress_test.sh - 可复现的 CPU内存混合压测 set -euo pipefail DURATION${1:-60s} CPU_WORKERS${2:-2} VM_WORKERS${3:-1} VM_BYTES${4:-256M} LOG_DIR/var/log/stress_test mkdir -p $LOG_DIR echo [$(date)] 开始压测: cpu$CPU_WORKERS vm$VM_WORKERS vm_bytes$VM_BYTES duration$DURATION # 后台启动观测 vmstat 1 $DURATION $LOG_DIR/vmstat.log 21 VMSTAT_PID$! # 启动 stress超时自动退出 stress --cpu $CPU_WORKERS --vm $VM_WORKERS --vm-bytes $VM_BYTES \ --timeout $DURATION --verbose $LOG_DIR/stress.log 21 # 等待观测进程结束 wait $VMSTAT_PID 2/dev/null || true echo [$(date)] 压测结束日志在 $LOG_DIR echo --- vmstat 摘要 --- tail -5 $LOG_DIR/vmstat.log逻辑说明set -euo pipefail让脚本在出错时立即退出避免压测跑一半失败还继续。vmstat在后台采样日志落到独立目录方便事后分析。stress的--timeout保证不会无限运行。脚本最后输出 vmstat 的尾部数据快速判断压测期间的系统状态。参数说明DURATION默认 60 秒CPU_WORKERS默认 2VM_WORKERS默认 1VM_BYTES默认 256M。调用时按需覆盖比如./stress_test.sh 120s 4 2 512M。日志目录/var/log/stress_test需要写权限普通用户跑的话改成$HOME/stress_test。我自己的习惯是任何压测前先nproc和free -m确认资源基线压测中至少开两个终端分别看vmstat和dmesg压测后检查dmesg有没有 OOM 记录、df -h有没有磁盘写满。这套流程跑下来基本不会翻车。希望帮到你。本文还有配套的精品资源点击获取
返回列表