简介:本资源面向需要在无外网环境下完成Linux性能压测的运维与开发人员,提供CentOS平台stress工具的离线安装方案。压缩包共43个文件,约46.66MB,以rpm依赖包、configure与install等构建脚本、readme与changelog等说明文档、texinfo与html帮助文档及C源码文件为主,覆盖从依赖安装到编译部署的完整链路,并附带sar命令相关组件,便于在隔离网络中同步完成系统资源监控与压力测试。资源核心为stress-1.0.4.tar源码包,配合gcc-g++等rpm依赖,可支撑CPU、内存、IO等维度的压测场景,适合中高级Linux运维人员排查性能瓶颈、验证系统稳定性。目前已有2589人学习下载,读者可据此快速搭建离线压测环境,掌握依赖补齐、源码编译与sar数据采集的完整流程,减少在无网环境中反复试错的成本。
1. 内网机器压测怎么破:从零搞定 CentOS 离线部署 stress
上周帮一个做私有云交付的朋友处理了个挺典型的问题:客户机房在完全隔离的内网里,几十台 CentOS 7.9 的机器要上线前做稳定性压测,但现场没有外网,yum 源也连不上,yum install stress直接报错。他试过从别的机器拷 rpm 包过去,结果依赖一个接一个地缺,折腾了一下午没搞定。其实这种场景在金融、能源、制造业的内网环境里太常见了——离线安装 stress 这件事本身不难,难的是把依赖链理清楚、把参数调对、把结果看明白。这篇就把我实际用过的离线部署流程和压测参数配置完整拆一遍,从 rpm 包准备到多核 CPU、内存、IO 混合压测,再到怎么判断机器到底稳不稳,新手照着走能复现,熟手可以重点看参数边界和排查部分。
2. stress 工具选型与离线包准备:为什么不用 stress-ng
2.1 stress 和 stress-ng 的取舍
在离线环境里选压测工具,第一原则是依赖越少越好。stress这个工具非常老牌,源码只有一个 C 文件,编译出来就一个二进制,运行时只依赖 glibc,几乎不存在动态库缺失的问题。stress-ng功能确实强得多,支持几百种压力模式,但它的编译依赖和运行时依赖都更复杂,在 CentOS 7 这种老系统上离线编译经常卡在依赖版本上。
我一般的判断标准是这样的:如果只是验证 CPU、内存、磁盘 IO 的基本稳定性,stress完全够用;如果需要测特定系统调用、网络协议栈、调度器行为,才考虑stress-ng。内网交付场景里 90% 的需求就是「跑满 CPU 看会不会宕机」「吃满内存看 OOM killer 会不会触发」「持续写磁盘看会不会掉盘」,这些stress都能覆盖。
注意:CentOS 7 的 base 源里其实有 stress 的 rpm 包,但版本是 1.0.4,比较老。如果对版本没要求,直接拿这个 rpm 最省事;如果要新版本特性(比如
--backoff参数),就得自己编译。
2.2 离线 rpm 包的获取与依赖梳理
最稳妥的方式是在一台同版本、同架构的 CentOS 机器上(可以是虚拟机)用yumdownloader把 rpm 和依赖全部拉下来。具体操作:
# 在一台有网的 CentOS 7 机器上执行 # 先安装 yum-utils,它提供 yumdownloader 命令 yum install -y yum-utils # 创建存放目录 mkdir -p /tmp/stress-offline # 下载 stress 及其所有依赖的 rpm 包 # --resolve 会自动解析依赖,--destdir 指定下载目录 yumdownloader --resolve --destdir=/tmp/stress-offline stress # 查看下载了哪些包 ls -lh /tmp/stress-offline/执行完之后你会看到目录里除了stress-1.0.4-*.rpm之外,可能还有libgomp、libstdc++之类的依赖包。CentOS 7 上 stress 的依赖其实很少,通常就两三个包。
逻辑说明:yumdownloader --resolve是关键,它会递归解析依赖树,把所有需要的 rpm 都下载到指定目录。--destdir必须用绝对路径,用相对路径有时候会出问题。如果目标机器和下载机器的 CentOS 小版本不一致(比如 7.6 vs 7.9),glibc 版本可能有差异,建议尽量保持版本一致。
参数说明:--resolve是递归解析依赖;--destdir指定输出目录;如果只想下载不安装,不加--installroot就行。下载完成后可以用rpm -qpR stress-*.rpm查看这个包具体依赖哪些库,确认没有遗漏。
2.3 源码编译方式的离线包制作
如果 rpm 版本太老或者你需要特定版本,源码编译是更灵活的方式。stress 的源码包很小,编译也简单:
# 在有网的机器上下载源码 wget https://example.com/stress-1.0.4.tar.gz # 解压 tar -xzf stress-1.0.4.tar.gz cd stress-1.0.4 # 编译(需要 gcc 和 make) ./configure make # 编译完成后,stress 二进制就在当前目录 # 用 ldd 检查它依赖哪些动态库 ldd ./src/stress逻辑说明:./configure会检查编译环境,make生成二进制。编译完之后用ldd看依赖,正常情况下只依赖libc.so.6、libm.so.6、libgomp.so.1这几个基础库,CentOS 7 默认都有。如果ldd显示not found,说明目标机器缺对应的库,需要把库文件也一起拷过去。
参数说明:./configure可以加--prefix指定安装路径,但离线场景下我一般不用make install,直接把src/stress这个二进制拷到目标机器/usr/local/bin/下就行,省事。注意编译机器的 glibc 版本不能高于目标机器,否则二进制跑不起来,会报GLIBC_2.XX not found。
3. 离线部署实操:rpm 安装与二进制分发两条路
3.1 rpm 方式安装与依赖处理
把上一步下载好的整个目录打包,通过 U 盘或者内网文件服务器传到目标机器。假设传到了/tmp/stress-offline/,安装命令:
# 进入 rpm 存放目录 cd /tmp/stress-offline # 用 rpm 一次性安装目录下所有包 # -i 安装,-v 显示详情,-h 显示进度条 rpm -ivh *.rpm # 如果提示依赖冲突或已安装,改用 -U 升级安装 rpm -Uvh *.rpm # 验证安装 which stress stress --version逻辑说明:rpm -ivh *.rpm会按文件名顺序安装,如果依赖包在 stress 主包后面,可能会先报依赖错误。更稳妥的做法是先装依赖包再装主包,或者直接用yum localinstall:
# yum localinstall 会自动处理本地 rpm 的依赖顺序 yum localinstall -y /tmp/stress-offline/*.rpm参数说明:-i是安装,-U是升级(已安装时用),-v详细输出,-h显示进度。yum localinstall的好处是它会自动从本地目录解析依赖关系,不用手动排序。如果目标机器完全没有 yum 源配置,yum localinstall可能会报「Cannot retrieve repository metadata」,这时候需要先把/etc/yum.repos.d/下的源文件临时禁用,或者直接用rpm命令手动按顺序装。
3.2 二进制直接分发方式
如果目标机器连 rpm 都不想用,或者你用的是源码编译出来的二进制,直接拷贝就行:
# 在目标机器上创建目录 mkdir -p /usr/local/bin # 从 U 盘或共享目录拷贝二进制 cp /mnt/usb/stress /usr/local/bin/stress # 赋予执行权限 chmod +x /usr/local/bin/stress # 验证 stress --version逻辑说明:这种方式最干净,不涉及包管理器,也不会因为 rpm 数据库损坏而失败。但前提是你已经用ldd确认过目标机器有所有依赖库。如果运行时报error while loading shared libraries: libgomp.so.1,说明缺 libgomp,需要把对应的.so文件也拷过去放到/usr/lib64/下。
参数说明:chmod +x必须有,否则会报权限拒绝。/usr/local/bin默认在 PATH 里,放这里可以直接用stress命令。如果不想污染系统目录,也可以放在/opt/stress/bin/下,然后手动加 PATH 或者用绝对路径调用。
3.3 验证安装与基础冒烟测试
装完之后别急着上生产压测,先跑个短时间的冒烟测试确认工具本身没问题:
# 启动 2 个 CPU 压测进程,持续 10 秒 stress --cpu 2 --timeout 10s # 观察输出,正常情况会看到类似: # stress: info: [12345] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd # stress: info: [12345] successful run completed in 10s逻辑说明:--cpu 2表示启动 2 个 worker 进程做 CPU 密集型运算(本质是sqrt()循环),--timeout 10s表示 10 秒后自动退出。如果看到successful run completed,说明工具正常工作。如果卡住不动或者报错,检查系统负载和权限。
参数说明:--timeout支持s(秒)、m(分)、h(时)、d(天)单位。不加这个参数 stress 会一直跑到你手动 kill。冒烟测试建议用短时间,确认没问题再跑长时间压测。
4. 压测参数配置:CPU、内存、IO 混合场景怎么调
4.1 CPU 压测参数与核数匹配
CPU 压测是最常用的场景,核心参数就是--cpu N,N 等于要压的 worker 数量。这里有个常见误区:N 不是越大越好,也不是必须等于核数。
# 场景一:压满所有核心 # 先查看 CPU 核数 nproc # 假设输出是 8,则启动 8 个 CPU worker stress --cpu 8 --timeout 300s # 场景二:压一半核心,留余量给系统 stress --cpu 4 --timeout 300s # 场景三:超配压测,观察调度器行为 stress --cpu 16 --timeout 300s逻辑说明:--cpu 8在 8 核机器上会让每个核心都跑满,top里看到us(用户态)接近 100%。如果 N 超过核数,比如 16 个 worker 跑在 8 核上,每个 worker 分到的时间片减半,但总 CPU 使用率还是 100%,这种超配场景主要用来测试调度器在高负载下的表现。
参数说明:--cpu后面跟整数,表示 worker 进程数。--timeout控制持续时间。实际压测中我一般会配合--verbose看详细输出,但注意--verbose会刷屏,长时间压测建议重定向到文件。
4.2 内存压测与 OOM 边界
内存压测用--vm参数,它启动的 worker 会不断 malloc 和 free 内存。关键参数是--vm-bytes,控制每个 worker 分配多少内存。
# 启动 1 个内存 worker,每个分配 1GB,持续 60 秒 stress --vm 1 --vm-bytes 1G --timeout 60s # 启动 4 个 worker,每个 512MB,总共 2GB stress --vm 4 --vm-bytes 512M --timeout 60s # 配合 --vm-hang 让 worker 分配后保持不释放 stress --vm 2 --vm-bytes 1G --vm-hang 30 --timeout 120s逻辑说明:--vm 1启动一个内存压测进程,--vm-bytes 1G让它每次分配 1GB。默认行为是分配后立刻写入再释放,循环进行。--vm-hang 30表示分配后 sleep 30 秒再释放,这样能持续占用内存,更容易触发 OOM。
参数说明:--vm-bytes支持K、M、G单位,默认是字节。注意这个值是每个 worker 分配的,总内存 =--vm数量 ×--vm-bytes。如果总内存超过物理内存 + swap,系统会触发 OOM killer,这时候要观察dmesg里有没有Out of memory: Kill process的记录。
注意:内存压测有风险,可能触发 OOM 导致其他进程被杀。生产环境压测前务必确认没有关键业务在跑,或者用 cgroup 限制 stress 的内存使用上限。
4.3 IO 压测与磁盘稳定性验证
IO 压测用--io和--hdd两个参数。--io是同步写(调用sync()),--hdd是写临时文件。
# IO 压测:4 个 worker 不断调用 sync stress --io 4 --timeout 120s # HDD 压测:2 个 worker 写临时文件,每个 1GB stress --hdd 2 --hdd-bytes 1G --timeout 120s # 混合压测:CPU + 内存 + IO 同时上 stress --cpu 4 --vm 2 --vm-bytes 512M --io 2 --hdd 1 --timeout 300s逻辑说明:--io的 worker 会反复调用sync()把页缓存刷到磁盘,对磁盘写入压力较大。--hdd的 worker 会在当前目录创建stress.tmp文件并持续写入,--hdd-bytes控制每个 worker 写多少数据。混合压测是最接近真实业务场景的,能同时考验 CPU 调度、内存管理和磁盘 IO。
参数说明:--hdd默认写入当前工作目录,建议先cd到一个有大空间的目录再执行,比如/data/stress-test/。--hdd-bytes默认是 1GB,如果磁盘空间紧张可以调小。压测结束后记得清理生成的临时文件。
4.4 混合场景参数组合与监控命令
实际压测中很少只压单项,通常是组合场景。下面是一个我常用的混合压测模板:
# 混合压测脚本:CPU 8 核 + 内存 4G + IO 持续 10 分钟 stress --cpu 8 \ --vm 4 --vm-bytes 1G --vm-hang 10 \ --io 2 \ --hdd 1 --hdd-bytes 2G \ --timeout 600s \ --verbose 2>&1 | tee /var/log/stress-test.log逻辑说明:这个命令同时启动 CPU、内存、IO、HDD 四类 worker,--verbose输出详细信息,tee同时输出到屏幕和日志文件。压测过程中另开终端用监控命令观察系统状态。
参数说明:--vm-hang 10让内存 worker 分配后保持 10 秒,增加内存占用持续时间。--timeout 600s是 10 分钟。tee后面的日志路径要确保有写入权限。
配套的监控命令:
# 实时查看 CPU、内存、负载 top -b -d 1 -n 60 > /var/log/top-monitor.log # 查看内存和 swap 使用 free -h -s 5 # 查看磁盘 IO(需要 sysstat 包) iostat -x 5 60 # 查看 OOM 相关内核日志 dmesg -T | grep -i "out of memory"逻辑说明:top -b -d 1 -n 60表示批处理模式,每秒刷新一次,共 60 次,输出到文件。free -h -s 5每 5 秒刷新内存使用。iostat -x 5 60每 5 秒输出一次磁盘扩展统计,共 60 次。dmesg -T带时间戳查看内核日志,过滤 OOM 关键字。
参数说明:-b是 batch 模式,适合重定向;-d是刷新间隔;-n是刷新次数。iostat的-x显示扩展统计,包括%util(磁盘利用率)、await(平均等待时间)等关键指标。
5. 避坑与排查:离线压测最容易翻车的五个点
5.1 现象:rpm 安装报依赖缺失,但依赖包明明在目录里
原因:rpm -ivh *.rpm按 shell 展开的文件名顺序安装,如果 stress 主包排在依赖包前面,rpm 会先检查依赖,发现缺失就报错退出,不会自动跳到下一个包。
解决:用yum localinstall代替rpm -ivh,它会自动解析依赖顺序。或者手动先装依赖包:rpm -ivh libgomp-*.rpm然后再rpm -ivh stress-*.rpm。如果 yum 源不可用,加--disablerepo=*参数禁用所有远程源。
5.2 现象:二进制拷贝到目标机器后运行报 GLIBC 版本不匹配
原因:编译机器的 glibc 版本高于目标机器。CentOS 7.9 的 glibc 是 2.17,如果你在 CentOS 8 上编译,glibc 是 2.28,拷到 7.9 上就会报GLIBC_2.28 not found。
解决:在最低版本的目标系统上编译,或者直接用 rpm 包安装(rpm 包会声明依赖的 glibc 版本,安装时就能发现不匹配)。用objdump -T /usr/local/bin/stress | grep GLIBC可以查看二进制依赖的 glibc 版本。
5.3 现象:内存压测跑着跑着 SSH 断了,机器无响应
原因:--vm-bytes设置过大,总内存超过物理内存 + swap,触发 OOM killer。如果 OOM killer 杀掉了 sshd 或者关键系统进程,就会导致无法登录。
解决:压测前用free -h确认可用内存,--vm数量 ×--vm-bytes不要超过可用内存的 80%。更安全的做法是用 cgroup 限制 stress 的内存上限:
# 创建 cgroup 限制内存为 2G cgcreate -g memory:/stress-test cgset -r memory.limit_in_bytes=2G /stress-test # 在 cgroup 中运行 stress cgexec -g memory:/stress-test stress --vm 2 --vm-bytes 1G --timeout 60s5.4 现象:IO 压测把磁盘写满了,系统报 No space left on device
原因:--hdd默认在当前目录写stress.tmp文件,--hdd-bytes默认 1GB,多个 worker 同时写会快速消耗磁盘空间。
解决:压测前cd到一个大容量分区,比如/data/,并且用--hdd-bytes控制单个文件大小。压测结束后手动删除stress.tmp文件。更稳妥的做法是提前用df -h确认目标分区剩余空间大于--hdd数量 ×--hdd-bytes。
5.5 现象:stress 进程 kill 不掉,一直占用 CPU
原因:stress 的 worker 进程是父子结构,直接kill父进程可能留下孤儿 worker 进程继续跑。或者用了--timeout但时间没到,手动 kill 时只杀了主进程。
解决:用pkill -9 stress杀掉所有 stress 相关进程。如果还不行,用ps -ef | grep stress找到所有 PID 逐个kill -9。预防措施是压测时始终加--timeout,让工具自己退出。
6. 压测结果怎么看:从数据到结论的最后一公里
压测跑完不是看个热闹就完了,关键是从监控数据里读出机器的真实状态。我一般会重点看四个指标:CPU 的%idle是否长期低于 5%、内存的available是否持续下降、磁盘的%util是否长期接近 100%、以及dmesg里有没有硬件报错。
具体来说,CPU 压测时如果top里us和sy加起来接近 100% 但id还有余量,说明 CPU 没跑满,可能是 worker 数不够或者有 IO 等待。内存压测时如果free的available降到很低但没触发 OOM,说明内存管理正常;如果dmesg出现Out of memory,说明内存不够用。磁盘 IO 压测时iostat -x的%util如果持续 100% 且await超过 50ms,说明磁盘是瓶颈。
还有一个容易被忽略的点:压测结束后不要立刻下结论,等系统负载降下来再观察 5 分钟。有些问题(比如内存泄漏、磁盘缓存回写)在压测停止后才会暴露。我习惯在压测结束后再跑一轮stress --cpu 1 --timeout 60s做恢复性测试,确认系统能正常回到低负载状态。
从那以后我每次离线压测都强制走一遍「冒烟测试 → 单项压测 → 混合压测 → 恢复观察」的流程,再急也不跳过冒烟那一步。希望帮到你。
本文还有配套的精品资源,点击获取