
1. 项目概述为什么你需要掌握stress-ng如果你负责过服务器运维、性能调优或者开发过对稳定性要求极高的后端服务那你一定对“压力测试”这个词不陌生。简单说压力测试就是给系统“上强度”看看它在极限负载下会不会“掉链子”。市面上压力测试工具很多从重量级的JMeter、Locust到各种云平台提供的压测服务选择不少。但很多时候我们需要的是一个轻量、灵活、能深入到系统底层CPU、内存、I/O、进程调度的工具来模拟那些“刁钻”的异常场景。这时stress-ng就该登场了。stress-ng是经典工具stress的“威力加强版”。它不是一个模拟业务逻辑的压测工具而是一个“系统资源压力施加器”。它的核心思想是通过启动大量特定的工作负载worker持续消耗特定的系统资源从而制造出CPU满载、内存吃紧、磁盘IO飙升、大量进程切换等压力环境。这对于评估系统在极端情况下的稳定性、发现内核或硬件的潜在缺陷、验证监控告警阈值、甚至测试散热和电源的冗余能力都至关重要。很多人对stress-ng的印象可能还停留在stress -c 4让CPU跑满的初级阶段。这就像只学会了开车但不知道如何应对冰雪路面、陡坡和紧急避让。实际上stress-ng拥有超过280种不同的压力测试方法stressors涵盖了从CPU浮点运算、内存带宽、文件系统操作到网络、管道、信号量乃至虚拟内存管理等方方面面。从新手到高手差距就在于能否精准、高效地运用这些方法组合出符合真实场景的“压力配方”。本文将从五个核心技巧出发带你从“会用”到“精通”。我们将不仅讲解命令怎么敲更会深入探讨每个技巧背后的设计逻辑、适用场景以及避坑指南。无论你是想快速验证新服务器的基线性能还是想复现一个棘手的线上性能抖动问题这些技巧都能让你手中的stress-ng从一把“锤子”变成一套精密的“手术刀”。2. 技巧一精准定位压力源——理解并选择正确的stressor新手使用stress-ng最常见的误区就是“暴力施压”比如一上来就stress-ng --cpu 8 --io 4 --vm 2 --vm-bytes 1G --timeout 60s。这确实能让系统“冒汗”但产生的压力是混杂的你很难判断究竟是CPU瓶颈、内存瓶颈还是IO瓶颈导致了系统响应变慢。高手的第一步是学会“精准打击”。2.1 认识stressor家族stress-ng的强大源于其丰富的stressor。你可以通过stress-ng --class list查看所有压力类别或者用stress-ng --cpu-method list查看CPU压力下的具体算法。理解几个核心类别至关重要cpu: 通用CPU压力。默认使用rand方法混合整数和浮点运算但你可以通过--cpu-method指定更具体的方法如matrix矩阵乘法考验浮点和缓存、fft快速傅里叶变换高强度浮点、all轮换使用所有方法。vm: 虚拟内存压力。通过分配内存并频繁访问来制造内存和内存总线压力。--vm-bytes控制每个worker分配的大小--vm-keep决定是否一直持有内存。io: 通用IO压力。创建worker来执行sync、cache淘汰、目录操作等对文件系统缓存和块设备产生压力。hdd: 磁盘IO压力。专门针对块设备进行读写可以指定--hdd-bytes写入的数据量对磁盘吞吐量和延迟是直接考验。memrate: 内存带宽压力。这是stress-ng的“大杀器”之一通过不同的内存访问模式如顺序、随机、指针追逐来测量内存的实际带宽和延迟对诊断内存性能瓶颈极有帮助。2.2 如何选择从场景出发选择哪个stressor取决于你的测试目标场景A验证CPU算力与散热。你想知道新服务器的持续满载频率是否达标散热能否扛住。这时应该使用纯净的CPU压力并避免其他资源成为瓶颈。# 使用所有CPU核心采用高强度的浮点运算方法持续5分钟 stress-ng --cpu $(nproc) --cpu-method fft --timeout 300s注意$(nproc)会自动获取系统的CPU核心数。使用fft或matrix能让CPU功耗和温度上升得更快更易暴露散热问题。同时用perf或turbostat工具监控CPU频率和温度是关键。场景B复现内存泄漏或OOM内存耗尽场景。你想测试应用在内存紧张时的行为或者验证监控系统的OOM告警。# 启动2个vm worker每个尝试分配1.5G内存根据系统总内存调整持续持有运行30秒 stress-ng --vm 2 --vm-bytes 1.5G --vm-keep --timeout 30s实操心得--vm-keep参数非常重要。如果不加worker会不断地分配和释放内存产生的是内存管理压力频繁的malloc/free和页错误。加上--vm-keep才是模拟“内存被应用长期占用”的场景更容易触发系统开始交换swap或直接触发OOM Killer。场景C测试数据库服务器的磁盘IO能力。数据库经常有大量随机读写。简单的--io可能不够需要更贴近磁盘的测试。# 使用4个worker进行随机写操作每个写入1G数据操作完成后清理文件 stress-ng --hdd 4 --hdd-bytes 1G --hdd-op write,rand --timeout 60s --metrics-brief排查技巧配合iostat -x 1命令观察磁盘的%util利用率、await平均等待时间和svctm平均服务时间。如果%util持续接近100%且await远高于svctm说明磁盘已完全饱和队列堆积严重。从新手到高手的跨越就是从“让系统忙起来”变为“让系统的某个特定部分按我预期的方式忙起来”。花时间阅读man stress-ng和stress-ng --class help了解每个压力源的特性是成为高手的基础。3. 技巧二压力编排的艺术——组合、序列与比例控制单一的压力源测试往往不够真实。线上问题常常是多种资源同时出现瓶颈导致的。例如一个视频转码服务可能同时吃满CPU、大量读写临时文件、并占用不少内存。stress-ng允许你像导演一样编排一场复杂的“压力交响乐”。3.1 并行组合压力使用多个--前缀的参数即可并行启动多种压力。# 模拟一个计算密集型内存密集型应用8个CPU worker2个内存worker各占512M运行2分钟 stress-ng --cpu 8 --vm 2 --vm-bytes 512M --timeout 120s这个命令会同时启动两组worker它们会竞争系统资源。你需要关注的是系统的整体表现以及top或htop中各个资源us/syCPU、mem、io的饱和度。3.2 序列化压力阶段高级技巧更真实的场景是压力有阶段性变化。stress-ng本身不直接支持“先A后B”的序列但我们可以利用Shell脚本或任务调度器如cron或at来实现。#!/bin/bash # 脚本phased_stress.sh echo 阶段1: 高CPU压力持续30秒 stress-ng --cpu $(nproc) --cpu-method matrix --timeout 30s --metrics-brief sleep 5 # 间歇5秒 echo 阶段2: 高内存压力持续20秒 stress-ng --vm 4 --vm-bytes 1G --vm-keep --timeout 20s --metrics-brief sleep 5 echo 阶段3: 混合压力CPUIO持续45秒 stress-ng --cpu 4 --io 2 --timeout 45s --metrics-brief这种测试非常适合验证系统的弹性恢复能力以及监控系统是否能准确捕捉到不同模式的性能波动。3.3 精细控制资源比例有时我们不想完全压满而是想制造一个“70% CPU 50% 内存”的稳态压力。这需要一些计算和技巧。CPU比例控制stress-ng的CPU worker默认会试图占满一个核心。如果你有8核启动4个worker理论上是50%的CPU占用。但实际由于操作系统调度和worker自身效率可能略低或略高。更精确的控制可以结合taskset绑定CPU和cpulimit工具但stress-ng自身通过--cpu-load参数可以设定目标CPU占用率百分比。# 启动8个worker但每个worker的目标是只使用50%的CPU时间理论上整体负载在50%左右波动 stress-ng --cpu 8 --cpu-load 50 --timeout 60s注意--cpu-load的实现原理是让worker在工作和睡眠间循环因此其产生的压力类型缓存命中率、分支预测与持续满载有所不同更适合模拟波动负载。内存比例控制通过--vm-bytes和--vm数量可以较精确地控制总的内存占用量。例如系统有16G内存想占用8G可以--vm 4 --vm-bytes 2G。务必使用--vm-keep来稳定占用。编排压力的核心思想是“建模”。在测试前先思考你的目标应用或场景的资源使用模型是什么样的是CPU尖峰还是内存缓慢增长是随机读IO还是顺序写IO根据模型来组合和调整你的stress-ng参数这样的测试结果才有参考价值。4. 技巧三从噪声中提取信号——掌握关键监控与度量方法施加压力只是手段观察系统的反应才是目的。如果压测时只盯着stress-ng自己的输出那就像蒙着眼睛开车。高手必须掌握一套监控组合拳将stress-ng的压力源与系统的性能指标关联起来。4.1 stress-ng自身的度量--metrics和--metrics-briefstress-ng在运行结束后会输出丰富的性能数据这是第一手资料。stress-ng --cpu 4 --vm 1 --vm-bytes 500M --timeout 30s --metrics-brief--metrics-brief会输出一个简洁的摘要包含bogo ops: 这是stress-ng自定义的“压力操作数”用于横向比较同一压力源下不同系统的性能。数字越大说明系统完成该压力操作的速度越快。注意不同压力源之间的bogo ops没有可比性。real time (usr/sys/total): 实际耗时、用户态CPU时间、内核态CPU时间。如果sys时间占比异常高可能意味着内核锁或系统调用存在瓶颈。cpu usage (usr/sys/total): 整个压测期间的平均CPU使用率。--metrics会输出更详细的数据包括运行期间的中位数、百分位数等。对于需要严谨分析的场景建议使用--metrics并将输出重定向到文件。4.2 系统级监控黄金组合在另一个终端或通过监控系统你需要观察以下核心指标CPU:mpstat -P ALL 1查看每个核心的利用率%usr,%sys,%iowait。如果%iowait在CPU压力测试时很高说明存储是瓶颈。内存:free -h或vmstat 1free看剩余内存和缓冲/缓存。vmstat看siswap in和soswap out如果它们大于0说明物理内存不足发生了交换性能会急剧下降。磁盘IO:iostat -x 1%util: 设备利用率。100%表示饱和。await: 平均I/O等待时间毫秒。越高说明队列越长。svctm: 平均服务时间毫秒。接近磁盘的物理性能。r/s,w/s: 每秒读写次数。rkB/s,wkB/s: 每秒读写吞吐量KB。系统负载与进程:top或htopload average: 1/5/15分钟平均负载。如果持续高于CPU核心数说明系统过载。观察stress-ng子进程的状态和资源占用。4.3 关联分析与问题定位真正的技巧在于关联分析。例如你运行stress-ng --hdd 2进行磁盘压测但发现iostat显示磁盘%util只有50%但await高达100ms。top显示%sysCPU 占用率很高。stress-ng输出的 bogo ops 很低。这很可能不是磁盘本身慢而是文件系统或内核IO调度器遇到了瓶颈比如锁竞争。这时你的测试重点就应该从硬件转向软件配置。一个高手常用的方法是“分层剥离”先施加单一、纯净的压力如纯CPUmatrix记录下此时的系统表现如CPU频率、温度、bogo ops作为基线。然后逐步叠加其他压力如内存压力观察基线指标如何变化。如果叠加内存压力后纯CPU的bogo ops下降了说明内存带宽或延迟影响了CPU算力的发挥这可能是NUMA架构或内存通道配置的问题。5. 技巧四模拟极端与异常场景——超越常规负载测试常规的压力测试是看系统“能跑多快”而高手的压力测试还要看系统“有多耐操”即在异常和极端情况下的表现。stress-ng提供了很多用于“破坏性”测试的stressor。5.1 缓存与内存子系统压力--cache与--cache-fence: 这些压力源会针对CPU的各级缓存L1/L2/L3进行冲刷和争夺非常适合测试多核共享缓存时的性能影响以及验证内存屏障memory barrier相关代码的正确性。# 启动4个worker专门进行缓存行级别的伪共享false sharing压力测试 stress-ng --cache 4 --cache-fence --timeout 60s这种测试可能让程序出现一些在低负载下永远不会出现的、诡异的并发BUG。--memrate测内存真实带宽: 这是性能调优的利器。不同的访问模式顺序、随机对内存带宽的利用率天差地别。# 测量顺序读取的内存带宽 stress-ng --memrate 1 --memrate-op seqrd # 测量随机读取的内存延迟通过指针追逐 stress-ng --memrate 1 --memrate-op randrd将结果与主板、内存的理论带宽对比可以判断内存配置是否达到最优。5.2 进程与调度器压力--fork大量创建进程: 模拟“fork炸弹”或微服务频繁重启的场景测试进程描述符表、调度器的极限。# 每秒钟尝试fork 100个子进程持续30秒 stress-ng --fork 100 --fork-max 500 --timeout 30s重要警告这类测试非常危险可能导致系统瞬间无响应。务必在测试机上操作并设置合理的--fork-max上限和较短的--timeout。同时使用ulimit -u检查并可能调整系统的最大用户进程数nproc。--sched调度策略压力: 让大量worker在不同的调度策略SCHED_OTHER,SCHED_FIFO,SCHED_RR之间切换和竞争测试实时调度器的行为。5.3 文件系统与磁盘元数据压力--dentry和--dir: 创建和删除大量的目录项dentry和目录这对文件系统的元数据性能是巨大考验。像ext4在小文件创建删除场景下的表现可以用这个来测试。# 创建深度目录结构和大量文件链接测试文件系统元数据操作 stress-ng --dentry 4 --dir 2 --timeout 120s运行这个命令时用df -i观察 inode 使用情况会很有趣。进行这类极端测试时有两条铁律明确目标你为什么要模拟这个场景是为了验证系统的某个特定限制如pid_max还是为了测试内核的某个新特性如内存压缩没有目标的破坏性测试只是捣乱。做好隔离与恢复务必在独立的测试环境虚拟机、容器或专用物理机中进行。准备好系统重启甚至重装的心理准备和物理准备。在执行前保存好所有重要数据和工作状态。6. 技巧五集成与自动化——将stress-ng融入你的工作流对于高手而言stress-ng不应该是一个手动执行的玩具而应该是一个可以集成到CI/CD持续集成/持续部署、自动化测试框架和监控演练中的强大工具。6.1 编写可复用的压测脚本将前面提到的技巧封装成Shell脚本或Python脚本参数化关键变量如持续时间、压力强度、目标资源。#!/bin/bash # 脚本stress_profile.sh # 用法./stress_profile.sh profile duration # profile: cpu, memory, io, mixed # duration: 秒数 PROFILE$1 DURATION$2 LOG_DIR./stress_logs mkdir -p $LOG_DIR TIMESTAMP$(date %Y%m%d_%H%M%S) case $PROFILE in cpu) STRESS_CMDstress-ng --cpu $(nproc) --cpu-method all --timeout ${DURATION}s --metrics-brief LOG_FILE${LOG_DIR}/cpu_${TIMESTAMP}.log ;; memory) # 分配总内存的70% TOTAL_MEM$(free -b | awk /^Mem:/{print $2}) VM_BYTES$((TOTAL_MEM * 70 / 100)) STRESS_CMDstress-ng --vm 4 --vm-bytes ${VM_BYTES} --vm-keep --timeout ${DURATION}s --metrics-brief LOG_FILE${LOG_DIR}/memory_${TIMESTAMP}.log ;; io) STRESS_CMDstress-ng --hdd 2 --hdd-bytes 10G --hdd-op write,seq --timeout ${DURATION}s --metrics-brief LOG_FILE${LOG_DIR}/io_${TIMESTAMP}.log ;; mixed) STRESS_CMDstress-ng --cpu 2 --vm 1 --vm-bytes 1G --hdd 1 --hdd-bytes 5G --timeout ${DURATION}s --metrics-brief LOG_FILE${LOG_DIR}/mixed_${TIMESTAMP}.log ;; *) echo Unknown profile: $PROFILE exit 1 ;; esac echo Starting $PROFILE stress test for ${DURATION}s, logging to $LOG_FILE echo Command: $STRESS_CMD $LOG_FILE echo $LOG_FILE # 在后台启动系统监控 sar -u -r -d -p 1 $DURATION ${LOG_FILE}.sar 21 SAR_PID$! # 执行压测并记录输出 eval $STRESS_CMD $LOG_FILE 21 wait $SAR_PID echo Stress test completed. Log saved to $LOG_FILE这个脚本提供了基本的框架你可以扩展更多场景并集成告警如压测期间如果系统负载超过某个阈值则发通知。6.2 与CI/CD管道集成在部署新版本的应用或内核前自动运行一组压力测试确保基础性能没有退化Performance Regression。在CI服务器如Jenkins、GitLab CI上安装stress-ng。定义基准测试针对你的应用特点定义一组标准的stress-ng命令如混合CPU内存压力。编写CI任务在部署流程中插入一个阶段在新环境中运行这组压力测试。收集与比较指标解析stress-ng --metrics-brief的输出提取关键的bogo ops和cpu usage。与历史基准值如上次稳定版本的测试结果进行比较。设置质量门禁如果关键指标如bogo ops下降超过10%或者系统在压力下出现了异常如OOM则自动失败该CI任务阻止有性能退化的代码被部署。6.3 监控系统与混沌工程演练在混沌工程实践中stress-ng是一个完美的“故障注入”工具。演练内存压力定期在非生产环境的某个节点上执行stress-ng --vm触发内存告警验证监控系统如Prometheus Alertmanager的告警是否及时、准确以及运维人员的响应流程是否顺畅。演练CPU抢占模拟某个异常进程吃满CPU观察你的服务网格或调度器如Kubernetes的限流和驱逐机制是否生效。关键技巧资源限制cgroup在容器化环境中一定要在cgroup限制内进行测试。你可以使用docker run的--cpus、--memory参数或者直接在Kubernetes Pod的resources.limits中设置限制然后在这个限制范围内运行stress-ng。这能更真实地模拟容器内应用遇到资源竞争的情况。自动化集成的核心价值在于“持续验证”。将压力测试从一次性的、手动的、探索性的活动转变为系统的、自动化的、可重复的保障环节。这能让你在每次基础设施变更、内核升级或应用发布时都对其稳定性多一份信心。7. 常见问题与排查技巧实录即使掌握了所有技巧在实际操作中还是会遇到各种“坑”。下面是我在多年使用中积累的一些典型问题及其解决方法。7.1 问题压测命令执行后系统完全卡死无法响应可能原因1触发了OOM Killer但关键进程被杀导致系统异常。排查重启后查看内核日志dmesg | grep -i kill。解决压测内存时务必计算好总量为系统和其他关键进程如SSH留出足够内存。可以使用--vm-keep先稳定占用观察free和vmstat的si/so确保不会进入swap颠簸状态。可能原因2--fork或--sched等压力源创建了海量进程/线程耗尽了PID或线程数限制。排查检查/proc/sys/kernel/pid_max和ulimit -u。解决永远为这类测试设置--fork-max和较短的超时--timeout。在测试前可以临时调高限制echo 1000000 /proc/sys/kernel/threads-max需root但测试后改回。7.2 问题CPU压力测试时top显示CPU使用率不到100%可能原因1CPU频率缩放Frequency Scaling的影响。现代CPU在空闲时会降频节能。排查安装cpupower或turbostat观察压测时的CPU实际频率。解决将CPU调控器governor设置为performance模式cpupower frequency-set -g performance。这能确保CPU运行在最高频率获得真实的峰值性能数据。可能原因2压力计算方法不够“重”。默认的rand方法可能在某些新CPU上效率过高或者被编译器优化了。解决换用更复杂的计算方法如--cpu-method matrix或--cpu-method fft。也可以增加每个worker的负载--cpu-ops或使用--cpu-load 100。7.3 问题磁盘IO压力测试结果波动很大且iostat显示%util很低可能原因写入了缓存未触及物理磁盘。默认情况下很多写操作会先进入页面缓存page cache异步刷盘。排查使用iostat -x 1观察wkB/s写吞吐和%util。如果wkB/s很高但%util很低很可能写在了缓存里。解决对于想要测试纯磁盘性能的场景需要绕过缓存。stress-ng的--hdd默认使用O_DIRECT或O_SYNC吗不一定。更可靠的方法是直接使用fio工具进行磁盘基准测试因为它对IO引擎的控制更精细。或者在stress-ng测试前手动清空缓存sync; echo 3 /proc/sys/vm/drop_caches需root生产环境慎用但这会改变系统整体状态。7.4 问题stress-ng报告很高的bogo ops但实际应用性能却很差可能原因压力模式与实际应用不匹配。stress-ng的bogo ops衡量的是它自己定义的操作的速度。如果你的应用是内存访问密集型指针追逐而测试用的是顺序内存带宽测试--memrate seq结果自然没有参考性。解决Profile你的应用。使用perf top、perf record或vtune等性能分析工具找出你应用的真实热点是CPU计算是缓存未命中还是特定的系统调用然后选择与之最匹配的stress-ngstressor 进行测试。例如应用受内存延迟影响大就用--memrate randrd。7.5 一份速查表参数与常见用途对照参数缩写主要用途关键注意事项--cpu N-c N通用CPU压力配合--cpu-method,--cpu-load进行精细控制--vm N-m N虚拟内存/内存压力务必理解--vm-keep的作用--vm-bytes控制大小--io N-i N通用IO压力文件系统、缓存产生的压力类型较杂需配合iostat分析--hdd N-d N块设备/磁盘IO压力使用--hdd-op指定读写模式--hdd-bytes控制数据量--fork N-F N进程创建压力极其危险必须设置--fork-max和短--timeout--metrics-brief-t输出简洁的性能摘要必选项用于获取测试结果--timeout T-t T设置测试运行时间如60s,5m,1h安全绳防止忘记停止--class无按类别列出或选择压力源探索工具的好帮手如stress-ng --class io--sequential N无顺序执行N种所有压力源用于快速全面的系统健壮性扫描但时间很长掌握这五个技巧意味着你不再只是stress-ng的用户而是成为了一个能够利用它主动发现、定位和验证系统性能问题的专家。记住所有压力测试的最终目的都是为了更好地理解你的系统从而构建出更稳定、更可靠的服务。